Project

General

Profile

Actions

Bug #21104

open

Net::HTTP connections failing in Ruby >= 3.4.0 on macOS with Happy Eyeballs enabled

Added by mjt58 (Mike Thompson) 4 days ago. Updated about 22 hours ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [arm64-darwin24]
[ruby-core:120855]

Description

A project I work on recently upgraded Ruby to 3.4.1 from 3.3.5. Following the upgrade, and when running locally on my Mac, all attempts to connect to an external service within the project over http(s) fail.

We use mise for managing development tool dependencies, including Ruby, and I am using macOS 15.3.

For example running something as simple as:

require 'net/http'
puts Net::HTTP.get(URI('https://bbc.co.uk'))

Will fail with the following stack trace:

/path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/protocol.rb:46:in 'OpenSSL::SSL::SSLSocket#connect_nonblock': Connection reset by peer - SSL_connect (Errno::ECONNRESET)
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/protocol.rb:46:in 'Net::Protocol#ssl_socket_connect'
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/http.rb:1736:in 'Net::HTTP#connect'
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/http.rb:1636:in 'Net::HTTP#do_start'
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/http.rb:1625:in 'Net::HTTP#start'
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/http.rb:1064:in 'Net::HTTP.start'
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/http.rb:824:in 'Net::HTTP.get_response'
	from /path/to/.local/share/mise/installs/ruby/3.4.1/lib/ruby/3.4.0/net/http.rb:805:in 'Net::HTTP.get'
	from request.rb:2:in '<main>'

I tried different versions of Ruby and confirmed that the issue appears with 3.4.0. After reading the release notes for this version, I tried setting RUBY_TCP_NO_FAST_FALLBACK=1 and this worked, allowing me to work around the problem.

This issue has also been encountered by others, please see:
https://github.com/rubygems/rubygems/issues/8390

Updated by shioimm (Misaki Shioi) 3 days ago

I suspect that this issue might be caused by an interaction between the specifications of Happy Eyeballs v2 and certain intermediate devices along the network path.
This is because, according to the report you linked, the problem occurs for some people but not for others, even though they are using the same OS, the same Ruby version, the same OpenSSL version, and connecting to the same destination (https://rubygems.org/). I also haven't been able to reproduce this issue in my own environment.

To help narrow down the cause, could you provide more information on the following?

  • You specified 'https://bbc.co.uk' as the host you're connecting to. Does the same issue occur when connecting to other hosts as well?
  • Does the issue still occur when you use a different network environment? For example, when connecting from your workplace, a cafe, or when using a VPN?

Updated by mjt58 (Mike Thompson) 2 days ago

shioimm (Misaki Shioi) wrote in #note-1:

To help narrow down the cause, could you provide more information on the following?

  • You specified 'https://bbc.co.uk' as the host you're connecting to. Does the same issue occur when connecting to other hosts as well?

Yes, I saw it first running bundle install with errors like:

Bundler::HTTPError Could not fetch specs from https://rubygems.org/ due to underlying error <Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://rubygems.org/specs.4.8.gz)>
  • Does the issue still occur when you use a different network environment? For example, when connecting from your workplace, a cafe, or when using a VPN?

Yes, I see it on, home wifi, office wifi and when tethered off my phone.

Updated by shioimm (Misaki Shioi) about 22 hours ago

@mjt58
Thank you for your reply. Since you're seeing this issue across different environments, I'm starting to think it's more likely influenced by software running on the host rather than a problem with network intermediaries.
Could you also check the following?

  • Do you get any errors when running TCPSocket.new directly without using net/http? For example, try executing a script like this:
require "socket"
p TCPSocket.new("bbc.co.uk", 80, fast_fallback: true)
  • Could you verify via packet capture whether the source IP of the RST is the client host itself? You can see which IP address sends an RST by using tcpdump, for example, by running sudo tcpdump -i <interface name> host bbc.co.uk, and then executing Net::HTTP.get(URI("https://bbc.co.uk")).

I'd appreciate your help with further debugging.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like1