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.
from
https://dev.to/madhuhari188/how-we-solved-unable-to-get-certificate-crl-in-rails-a-debugging-story-2pna
Comments
Post a Comment