title: Errno::EBADF: Bad file descriptor with ruby net/http
body: <p>What can cause while making an HTTP connection to return <strong>EBADF (Bad file descriptor).</strong></p>
  
  <p>Here is my following code wherein the HTTP connection is made. Although the error is very less now(happening very less) but before I put those error on rescue I need to understand what is the reason for the <strong>EBADF</strong></p>
  
  <pre><code>def make_http_request(url, headers={})
    uri = URI(url)
    Net::HTTP.start(uri.host, uri.port) do |http|
      req = Net::HTTP::Get.new(uri, headers)
      resp = http.request(req)
      if resp.code.to_i != 200
        logger.error "Retrieve #{resp.code} with #{url} and #{headers}"
        return false
      end
      return resp.body
    end
  rescue SocketError, Net::ReadTimeout, Errno::ECONNREFUSED =&gt; e
    logger.error "make_http_request #{url} with #{headers} resulted in #{e.message} \n #{e.backtrace}"
    return false
  end
  </code></pre>
  
  <p>I have a feeling that <code>connect syscall</code> is receiving an FD which ain't valid at that given point in time. But still unable to understand how can that happens.</p>
  
  <p>If it helps the code is used in an application that operates with multiple threads.</p>
  
  <p>In a nutshell, the definition of the above method looks like this...</p>
  
  <pre><code>module Eval
    def make_http_request(url, headers={})
      ...
      ...
      ..
    end
  
    def request_local_endpoint(url, headers)
       response = make_http_request(url, headers)
       response &amp;&amp; response.fetch('bravo',nil)
    end
  
    def request_external_endpoint(url, headers)
      response = make_http_request(url, headers)
      response &amp;&amp; response.fetch('token',nil)
    end
  end
  
  class RequestBuilder
    include Eval
    attr_reader :data
    def initialize(data)
      @data = data
    end
  
    def start
      token = request_external_endpoint('http://external.com/endpoint1',{'Content-Type'.freeze =&gt; 'application/json', 'Authorization' =&gt; 'abcdef'})
      return unless token
  
      result = request_local_endpoint('http://internal.com/endpoint1',{'Content-Type'.freeze =&gt; 'application/json'})
      return result
    end
  end
  
  10.times { 
     Thread.new { RequestBuilder.new('sample data').start }
  }
  </code></pre>