Skip to content
ecdsa.com
Ruby openssl (Net::HTTP verify_hostname, default true)Ruby

Error message

state=error: certificate verify failed (hostname mismatch)

Also printed as

  • OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:8443 state=error: certificate verify failed (hostname mismatch)

Full message: "SSL_connect returned=1 errno=0 peeraddr=<ip>:<port> state=error: certificate verify failed (hostname mismatch)". The host name itself is not part of the message; compare the URL with the certificate.

Ruby openssl (Net::HTTP verify_hostname, default true) — OpenSSL::SSL::SSLError from SSL_connect

What it means

The chain is trusted, but the host name Net::HTTP connected to does not appear in the certificate's Subject Alternative Names. Current Ruby versions let OpenSSL check the host name during the handshake (verify_hostname), so the problem surfaces as a certificate verification failure; older Rubies raised a separate "hostname … does not match the server certificate" error after connecting.

Why it happens

How to fix it

  1. 1.

    Compare the SAN list with the host

    The message does not include the names, so print them from the certificate.

    bash
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -ext subjectAltName
  2. 2.

    Use the certificate's name and pin the address

    Net::HTTP#ipaddr= connects to a given IP while SNI and verification use the host name.

    ruby
    # Connect to a specific address but verify the certificate's name (Net::HTTP#ipaddr=)
    http = Net::HTTP.new("www.example.com", 443)
    http.ipaddr = "10.0.0.5"
    http.use_ssl = true
    http.get("/health")
  3. 3.

    Reissue with every name in use

    Add the missing names to subjectAltName.

    bash
    openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \
      -addext "subjectAltName=DNS:api.example.com,DNS:www.example.com"

Related errors

Browse the full signature error database