Fixing RubyGems/Bundler SSL error


TL;DR: Skip to the solution.

Background

Recently, I upgraded my homebrew packages but I was still on OS X El Capitan.

Although I installed ruby with brew, my global ruby showed up as:

which ruby
/usr/bin/ruby
ruby -v
ruby 2.0.0p645 (2015-04-13 revision 50299) [universal.x86_64-darwin15]

My gem version was:

gem env version
2.0.14

Problem

When I tried to run the Jekyll server with Bundler:

bundle exec jekyll serve

I received the error:

Traceback (most recent call last):
        2: from /usr/local/bin/bundle:22:in `<main>'
        1: from /usr/local/Cellar/ruby/2.6.0/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/usr/local/Cellar/ruby/2.6.0/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (1.16.1) required by your path/to/project/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:1.16.1`

I followed the recommendation to update Bundler:

bundle update --bundler

But that didn’t fix the problem:

Traceback (most recent call last):
        2: from /usr/local/bin/bundle:22:in `<main>'
        1: from /usr/local/Cellar/ruby/2.6.0/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/usr/local/Cellar/ruby/2.6.0/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)

I tried installing Bundler:

gem install bundler

But no dice:

ERROR:  Could not find a valid gem 'bundler' (>= 0), here is why:
          Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: tlsv1 alert protocol version (https://rubygems.org/latest_specs.4.8.gz)

Troubleshooting

I ran an SSL check:

ruby -ropen-uri -e 'eval open("https://git.io/vQhWq").read'

And received the following:

Here's your Ruby and OpenSSL environment:

Ruby:           2.0.0p645 (2015-04-13 revision 50299) [universal.x86_64-darwin15]
RubyGems:       2.0.14
Compiled with:  OpenSSL 0.9.8zc 19 Mar 2015
Loaded version: OpenSSL 0.9.8zg 14 July 2015
SSL_CERT_FILE:  /System/Library/OpenSSL/cert.pem
SSL_CERT_DIR:   /System/Library/OpenSSL/certs

With that out of the way, let's see if you can connect to rubygems.org...

Bundler connection to rubygems.org:       failed  ❌  (uninitialized constant Bundler)
RubyGems connection to rubygems.org:      failed  ❌  (SSL/TLS protocol version mismatch)
Ruby net/http connection to rubygems.org: failed  ❌

Unfortunately, this Ruby can't connect to rubygems.org. 😡
Your Ruby can't connect to rubygems.org because your version of OpenSSL is too old. You'll need to upgrade your OpenSSL install and/or recompile Ruby to use a newer OpenSSL.

It seems that RubyGems version >=2 no longer works with OpenSSL version <1 as the SSL/TLS protocol has been updated.

I followed the official troubleshooting guide but I still encountered some difficulty.

Ultimately, I was able to solve the issue with 3 steps.

Solution

The resolution steps were:

  1. Uninstall Ruby from Homebrew
  2. Install or upgrade OpenSSL
  3. Install Ruby with rbenv

Uninstall Ruby from Homebrew

brew uninstall ruby

If you get the error:

Error: Refusing to uninstall /usr/local/Cellar/ruby/2.6.0
because it is required by vim, which is currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies ruby

I recommend you continue with the uninstallation because you’ll reinstall ruby in the following step.

Install or upgrade OpenSSL

brew install openssl # brew upgrade openssl

If you see the following:

which openssl
/usr/bin/openssl
openssl version -a
OpenSSL 0.9.8zg 14 July 2015
built on: Jul 31 2015
platform: darwin64-x86_64-llvm
options:  bn(64,64) md2(int) rc4(ptr,char) des(idx,cisc,16,int) blowfish(idx)
compiler: -arch x86_64 -fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O3 -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DMD32_REG_T=int -DOPENSSL_NO_IDEA -DOPENSSL_PIC -DOPENSSL_THREADS -DZLIB -mmacosx-version-min=10.6
OPENSSLDIR: "/System/Library/OpenSSL"

This means you’re still not using the correct binary. Follow the installation instructions and add the path to your shell configuration file:

echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bashrc

Reload your shell:

source ~/.bashrc

Confirm that the binary and version are correct:

which openssl
/usr/local/opt/openssl/bin/openssl
openssl version -a
OpenSSL 1.0.2q  20 Nov 2018
built on: reproducible build, date unspecified
platform: darwin64-x86_64-cc
options:  bn(64,64) rc4(ptr,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: clang -I. -I.. -I../include  -fPIC -fno-common -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/usr/local/etc/openssl"

Install Ruby with rbenv

Reinstall ruby with rbenv or rvm (they’re both version managers):

brew install rbenv && rbenv init

Reload your shell so rbenv is initialized correctly:

source ~/.bashrc

Install ruby:

rbenv install 2.6.0
ruby-build: use openssl from homebrew
Downloading ruby-2.6.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.bz2
Installing ruby-2.6.0...
ruby-build: use readline from homebrew
Installed ruby-2.6.0 to ~/.rbenv/versions/2.6.0

Set it as the global:

rbenv global 2.6.0

ruby will compile correctly when it’s built using the openssl binary from homebrew.

After reinstalling my project gems, I was able to get my Jekyll server running again:

bundle install && bundle exec jekyll serve


Please support this site and join our Discord!