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

Error message

verify error:num=19:self-signed certificate in certificate chain

Also printed as

  • verify error:num=19:self signed certificate in certificate chain
  • error 19 at 2 depth lookup: self-signed certificate in certificate chain

OpenSSL 3.x prints "self-signed", 1.1.1 "self signed". openssl verify reports it as "error 19 at <depth> depth lookup: …", where the depth is the root's position in the chain.

OpenSSL CLI (openssl s_client / openssl verify) — X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN

What it means

OpenSSL error 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN): the chain was built all the way up to a self-signed root certificate that came from the peer, and that root is not in the trusted store. Unlike error 18, there is a real CA hierarchy; unlike error 20, nothing is missing. The root must be trusted locally, or the connection is being intercepted.

Why it happens

How to fix it

  1. 1.

    Identify the root and its fingerprint

    Split the served chain and print subject, issuer and SHA-256 fingerprint of each certificate; compare the root's fingerprint with the one your IT or PKI team publishes.

    bash
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | awk '/BEGIN CERT/{n++} {print > ("cert" n ".pem")}'
    for f in cert[0-9]*.pem; do openssl x509 -in "$f" -noout -subject -issuer -fingerprint -sha256 2>/dev/null; done
  2. 2.

    Test with, then install, the correct root

    If -CAfile with the published root gives "Verify return code: 0 (ok)", install that root into the system store.

    bash
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com \
      -CAfile corp-root-ca.pem 2>&1 | grep 'Verify return code'
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates
  3. 3.

    Server owners: send leaf and intermediates only

    Sending the root wastes bytes in every handshake and never makes it trusted; distribute the root to clients instead.

    bash
    # Server owners: the root does not belong in the served chain
    cat server.pem intermediate.pem > fullchain.pem

Related errors

Browse the full signature error database