Skip to content
ecdsa.com
OpenSSL CLI (openssl s_client)OpenSSL CLI

Error message

verify error:num=21:unable to verify the first certificate

Also printed as

  • Verify return code: 21 (unable to verify the first certificate)

Printed by openssl s_client as "verify error:num=21:…" and "Verify return code: 21 (…)". Node.js reports the same condition as UNABLE_TO_VERIFY_LEAF_SIGNATURE ("unable to verify the first certificate").

OpenSSL CLI (openssl s_client) — X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE

What it means

OpenSSL error 21 (X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE): the chain consists of a single certificate, the server's own, and its issuer could not be found, so not even the leaf's signature can be checked. s_client usually prints error 20 for depth 0 right before it. The cure is almost always on the server: it must send its intermediate certificate.

Why it happens

How to fix it

  1. 1.

    Check what the server sends

    One certificate whose issuer (i:) is an intermediate CA confirms the problem.

    bash
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'
  2. 2.

    Serve leaf + intermediates

    Concatenate the leaf and the issuing intermediate(s) in order and configure the server with that file; print the bundle to check the order.

    bash
    # Build the file the server should use: leaf, then intermediates (issuer of each previous one)
    cat server.pem intermediate.pem > fullchain.pem
    openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout   # check the order
  3. 3.

    Find the correct intermediate

    The leaf's Authority Information Access extension names the URL of its issuer certificate; download it, convert to PEM if needed, and add it to the chain file.

    bash
    # Where to download the missing intermediate: the leaf's Authority Information Access URL
    openssl x509 -in server.pem -noout -ext authorityInfoAccess
    curl -sS -o intermediate.der http://ca.example.com/issuing-ca.crt
    openssl x509 -inform der -in intermediate.der -out intermediate.pem

Related errors

Browse the full signature error database