Search code examples
rubysslrubygemsssl-certificate

SSL verification error at depth 0: unable to get local issuer certificate (20)


My company uses a proxy for all internet traffic for security reasons, but unfortunately this breaks SSL with Ruby.

When I try gem install rake or any other gem command, I get the following error:

ERROR:  SSL verification error at depth 0: unable to get local issuer certificate (20)
ERROR:  You must add /C=US/ST=New York/L=New York City/O=My Company, Inc./OU=Corporate/CN=mycompany.com to your local trusted store
RubyGems connection to rubygems.org:      failed  ❌  (certificate verification)

How do I resolve this?


Solution

  • This error message means you are being routed through a domain whose SSL certificate is missing from your local certificate file. This happens commonly with web filters/proxies and can be fixed by adding the missing certificates.

    1. Use a web browser to see which certificate is missing
    2. Append it to your certificate file
    3. Make sure Ruby is using the file you think it is
    4. Test with Ruby's SSL check script

    1. Get SSL Certificate hash for the address in the error message

    The CN field towards the end of the error message tells you the address of the server, in my example mycompany.com. Open a web browser and go to this address. If you see a lock icon to the left of the URL, this means your browser found the SSL certificate (If not, you will have to find the missing certificate some other way).

    To get the certificate hash:

    • Click on the lock icon
    • Click "Details"
    • Select the top level certificate (this should match the original web address you got in the error message)
    • Click "Export". Save the file somewhere, it has the certificate hash.

    enter image description here enter image description here

    Will look something like this:

    -----BEGIN CERTIFICATE-----
    MIIESzCCAzOgAwIBAgIJAKNiDFgr+nN4MA0GCSqGSIb3DQEBCwUAMIG7MQswCQYD
    VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp
    [lots more stuff...]
    Z05JMrKlVndAmcLUoycD2hGqY9I1/9atfV23MkNslR+LBo7nMbjUj+lk/1rchww=
    -----END CERTIFICATE-----
    

    2. Locate Ruby's certificate file and append the server's certificate

    In a terminal, run:

    ruby -ropenssl -e 'p OpenSSL::X509::DEFAULT_CERT_FILE'
    

    You'll get a path:

    "C:/Ruby32-x64/bin/etc/ssl/cert.pem"
    

    Open this file in a text editor and add the certificate to the end. You can optionally add a comment to the new entry. Leave a newline above and below the entry and save the file:

    MYCOMPANY.com <- Comment line (optional) 
    ====================
    -----BEGIN CERTIFICATE-----
    [paste certificate hash here]
    -----END CERTIFICATE-----
    

    3. Make sure Ruby is using the right file

    In PowerShell:

    $env:SSL_CERT_FILE="C:\Ruby32-x64\bin\etc\ssl\cert.pem"
    

    In Command Prompt:

    set SSL_CERT_FILE=C:\Ruby32-x64\bin\etc\ssl\cert.pem
    

    4. Test it

    Save and run Ruby's SSL check script. You should see something like this:

    Here's your Ruby and OpenSSL environment:
    
    Ruby:           3.2.2p53 (2023-03-30 revision e51014f9c05aa65cbf203442d37fef7c12390015) [x64-mingw-ucrt]
    RubyGems:       3.4.10
    Bundler:        2.4.10
    Compiled with:  OpenSSL 3.1.0 14 Mar 2023
    Loaded version: OpenSSL 3.1.0 14 Mar 2023
    SSL_CERT_FILE:  C:/Ruby32-x64/bin/etc/ssl/cert.pem
    SSL_CERT_DIR:   C:/Ruby32-x64/bin/etc/ssl/certs
    
    With that out of the way, let's see if you can connect to rubygems.org...
    
    Bundler connection to rubygems.org:       success ✅
    RubyGems connection to rubygems.org:      success ✅
    Ruby net/http connection to rubygems.org: success ✅
    
    Hooray! This Ruby can connect to rubygems.org. You are all set to use Bundler and RubyGems. 👌