If youâve been around Rails long enough, youâve probably battled your fair share of SSL demons. But this one? This one had personality.
It was a Seahorse::Client::NetworkingError that failed only on macOS â yet worked perfectly inside Docker. The kind of âit works on my containerâ bug that makes you question every life choice leading up to this point.
So hereâs the story of how we chased down a ghostly SSL error, only to discover that the real culprit was⊠OpenSSL itself.
â ïž The Error
Seahorse::Client::NetworkingError
SSL_connect returned=1 errno=0 peeraddr=[...]
state=error: certificate verify failed (unable to get certificate CRL)
This popped up whenever our Rails app tried connecting to AWS S3 using the aws-sdk-ruby gem.
đ The Contradiction That Made No Sense
From the get-go, the bug refused to play by any rules of logic.
- â It failed locally but
- â Worked flawlessly in Docker
That told us one thing: the problem wasnât our code. It was the environment. macOS and Dockerâs Linux setup were behaving differently.
đ§Ș The âWait, What?â Moment
We decided to test the SSL connection manually, expecting it to fail the same way:
openssl s_client -connect 52.219.66.109:443 -servername s3.ap-south-1.amazonaws.com < /dev/null
Result?
Verify return code: 0 (ok)
So, macOSâs OpenSSL tool had no problem verifying the certificate. But Rails (and the AWS SDK) still choked on it.
At this point, confusion levels were high. Coffee consumption was higher.
đ§ The Real Test â Inside the Rails Console
To rule out any system-level differences, we went straight into rails c:
require 'aws-sdk-s3'
s3 = Aws::S3::Client.new(region: 'ap-south-1')
s3.list_buckets
Result:
certificate verify failed (unable to get certificate CRL)
Boom. So the system OpenSSL was fine, but Rubyâs built-in OpenSSL (via Net::HTTP) was throwing a tantrum.
đ§© The Root Cause â A Policy Change in OpenSSL
That cryptic message â âunable to get certificate CRLâ â turned out to be the key.
A CRL (Certificate Revocation List) is basically a âblacklistâ for certificates that have been revoked. The problem? The AWS certificate didnât actually have a CRL defined.
We checked with:
openssl s_client ... | openssl x509 -noout -text | grep "CRL Distribution Points"
Result:
X509v3 CRL Distribution Points:
# (empty)
Comparing environments made things click:
| Environment | OpenSSL Version | Result |
|---|---|---|
| macOS (failing) | 3.4.0 (new) | â Fails |
| Docker (working) | 3.0.11 (stable) | â Works |
Turns out, OpenSSL 3.4.0 introduced stricter validation rules. It now treats missing CRL entries as fatal errors â whereas the 3.0.x series simply shrugged and moved on.
So no, your Mac isnât broken â itâs just being too helpful.
đ The Fixes â Two Paths to Sanity
After a lot of trial (and some error), we landed on two solid fixes.
đ§© Fix 1: The Local-Only (Insecure but Practical) Workaround
Since this issue only showed up in development, one quick way to move on is to tell AWS SDK to skip SSL verification locally.
Create: config/initializers/aws_ssl_workaround.rb
# WARNING: LOCAL DEVELOPMENT ONLY
# OpenSSL 3.4.0 enforces stricter CRL policies, so skip verification here.
if Rails.env.development?
Aws.config.update(ssl_verify_peer: false)
end
â Pros:
- Works instantly
- Doesnât affect production
â ïž Cons:
- Insecure (but fine for local development)
đ§ Fix 2: Match Environments (I tried this one!)
The better long-term solution is to make your local OpenSSL match Dockerâs version.
-
Install an older OpenSSL (3.0.x):
brew install openssl@3.0 -
Reinstall Ruby:
rbenv uninstall 3.2.2 RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@3.0)" rbenv install 3.2.2 -
Reinstall gems:
gem install bundler bundle install
Now your local Ruby is linked against OpenSSL 3.0 â just like Docker and peace is restored.
đ§Ÿ Confirmation & References
Turns out, we werenât the only ones haunted by this ghost:
- openssl/openssl#28758 â CRL verification failures in OpenSSL 3.6.0
- ruby/openssl#949 â Net::HTTP failing due to stricter CRL rules
đĄ Takeaway
SSL errors can feel like black magic, but more often than not, theyâre version mismatches in disguise.
So next time something works in Docker but not on your laptop, remember: sometimes itâs not your code, itâs just your OpenSSL being extra.
Thanks for reading! If you found this helpful, share it with a fellow developer whoâs currently staring at an SSL error and losing their mind.
Top comments (1)
I just hit this the other day, too, and reached the same conclusions. Thanks for writing it up so I can just link folks here when they hit it.