The underlying connection was closed unexpectedly

Hello guys, I got suddenly Nemiro error on the code which used to work fine so far. Any idea why this happens and how to fix it? Thank you very much!

The underlying connection was closed: The connection was closed unexpectedly. —> Nemiro.OAuth.RequestException: The underlying connection was closed: The connection was closed unexpectedly.

I’m not sure if this is the same problem or even related, but I often see end of file reached (EOFError) from my Ruby code which talks to the API. Here’s a recent stacktrace:

/usr/local/lib/ruby/2.7.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
/usr/local/lib/ruby/2.7.0/net/protocol.rb:191:in `readuntil'
/usr/local/lib/ruby/2.7.0/net/protocol.rb:201:in `readline'
/usr/local/lib/ruby/2.7.0/net/http/response.rb:42:in `read_status_line'
/usr/local/lib/ruby/2.7.0/net/http/response.rb:31:in `read_new'
/usr/local/lib/ruby/2.7.0/net/http.rb:1528:in `block in transport_request'
/usr/local/lib/ruby/2.7.0/net/http.rb:1519:in `catch'
/usr/local/lib/ruby/2.7.0/net/http.rb:1519:in `transport_request'
/usr/local/lib/ruby/2.7.0/net/http.rb:1492:in `request'
/usr/local/lib/ruby/2.7.0/net/http.rb:933:in `start'
/usr/local/lib/ruby/2.7.0/net/http.rb:606:in `start'

This is with Ruby 2.7.2p137 (2020-10-01 revision 5445e04352).

I get this at least once a day on average.

Hi Josef and Andrew!
Apologies for not getting back to your earlier. To help us narrow down potential causes, do the errors you’re seeing occur only on certain types of requests (e.g. to a specific endpoint/using a specific method)?

Josef, in your case, is the Nemiro.OAuth.RequestException error persistent or intermittent? Could you give me the details of a recent request when it occured (ideally endpoint, timestamp, environment – sandbox or production – and the name of your integration)?

Andrew, has the EOFError been occurring for a while or did it start recently? Also – though it’s a complete shot in the dark – if you’re using Net::HTTP, does it happen to include a Connection: close header in your requests? I’ve noticed that Net::HTTP sometimes does this by default, even though connection-specific headers are not allowed in HTTP/2, and may cause errors similar to what you’re describing.

Best wishes,

Ewa

Hi Ewa!

I have seen the error on these endpoints:

  • access token refresh (POST)
  • bank transactions (GET)
  • bank transaction explanations (GET)
  • bank transaction explanation (POST)
  • categories (GET)
  • company (GET)
  • contacts (GET)
  • projects (GET)
  • user (GET)

These errors have been happening for at least 30 days (I only retain the error emails for 30 days) and probably a couple of months. I can’t remember if these errors were happening in, say, December. It feels like they have been happening a lot more in the past few weeks.

I’m using Net::HTTP with a 10s open timeout and a 90s read timeout. I’m not explicitly adding a Connection: close header. The code looks like this:

request = ... # it depends
response = Net::HTTP.start(uri.host, uri.port,
                           use_ssl: true,
                           open_timeout: 10,
                           read_timeout: 90) do |http|
  http.request request
end

I added http.set_debug_output $stderr just before http.request request and saw this on stderr:

Conn keep-alive

I’m not sure how to get Ruby to write out the headers.

Hi Andrew,

The reason why I mentioned the Connection: close header is that I recently ran into the same error with another (non-FreeAgent) API which started occurring on an endpoint I’ve been using consistently for a long time. Removing the header (by switching to the faraday gem as I also couldn’t find a way to do it in Net::HTTP) or changing its value to keep-alive resolved the problem for me, so if your Connection header is already set to keep-alive, it’s probably something different. Still, I’d be interested to hear if you encounter the same error using a different HTTP client? This could help us narrow down whether the problem sits with the Net::HTTP code or the FreeAgent API.

So far I’ve not been able to spot anything suspicious in the logs, are you able to check what code is returned for the responses that raise the error? Or is there a request that fails persistently which I could take under scrutiny or use to reproduce the issue?

Best wishes,

Ewa