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:
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