OpenSSL Certificate Chain Verification Failures: Diagnosis and Fixes
When openssl verify returns error 20 at depth 1, the client cannot locate the intermediate CA needed to complete the chain.
25 Feb 2026, 09:09 UTC

Recognizable Condition
Running openssl verify on a PEM file that includes a leaf certificate and one or more intermediate certificates produces the error 20: unable to get local issuer certificate at depth 1. The same symptom appears in TLS handshakes as certificate unknown or bad certificate alerts when the server presents a chain that the client’s trust store does not contain.
Diagnostic Table
| Error Code | Typical Cause |
|---|---|
| 20 | Missing intermediate in the trust chain (depth 1) |
| 10 | Expired intermediate certificate |
| 21 | Leaf certificate does not match the private key (modulus mismatch) |
| 27 | Certificate purpose or extension mismatch (e.g., not marked for TLS server use) |
Ordered Checks
- Run the verification command with explicit trust and intermediate files:
Permissions: execute permission on the OpenSSL binary; read permission on all PEM files. Risk: using a non‑existent file will cause a “file not found” error rather than the target verification error.openssl verify -CAfile /path/to/trust.pem -untrusted /path/to/intermediate.pem /path/to/leaf.pem - Inspect the full chain to verify that the intermediate is present and correctly ordered:
Check: each certificate’sopenssl crl2pkcs7 -nocrl -certfile /path/to/chain.pem | openssl pkcs7 -print_certs -nooutSubjectandIssuerfields should form a continuous chain from leaf to root. - Confirm certificate validity dates:
Result: the date must be in the future relative to the system clock; an expired intermediate will trigger error 10.openssl x509 -enddate -noout -in /path/to/leaf.pem - Match the leaf certificate with its private key by comparing modulus hashes:
If the MD5 digests differ, the key and certificate are mismatched, causing error 21.openssl x509 -noout -modulus -in leaf.pem | openssl md5 openssl rsa -noout -modulus -in key.pem | openssl md5
Fixes Tied to Findings
- Missing intermediate: add the intermediate to the
-untrustedargument or append it to the-CAfilestore. Example:
Risk: adding an untrusted intermediate expands the trust path; only do this when you control the issuing CA.openssl verify -CAfile /path/to/trust.pem -untrusted /path/to/missing_intermediate.pem leaf.pem - Expired intermediate: replace the intermediate with a fresh one and re‑issue the leaf if the key was also generated from the old certificate. Verify the new chain with the verification command.
- Key‑certificate mismatch: regenerate the private key from the existing certificate’s public key, or obtain a new certificate that matches the existing key. Re‑bundle the matching leaf and key into the server PEM before restarting the TLS service.
- Purpose/extension mismatch: adjust the certificate’s
subjectAltNameorextendedKeyUsageextensions, or use-purpose sslserveronly for diagnostic purposes; production deployments should use the correct purpose.
Escalation Criteria
Escalate if verification succeeds with -no_check_time or a custom trust store but fails in production, indicating a trust‑store configuration drift that may affect other services. Escalate further if the private key modulus does not match the certificate; this requires re‑issuing the certificate rather than a configuration change.
Cautions and Version‑Specific Limitations
- OpenSSL 3.x enforces a default security level that rejects legacy algorithms (e.g., SHA‑1 signatures, RSA keys <2048 bits). Use
-security_level 0only for temporary diagnostics; never in production. - Do not place an intermediate certificate in the client trust store unless you are the issuing CA; this widens the trust anchor and can accept unintended chains.
- OpenSSL 1.1.1 is end‑of‑life; OpenSSL 3.x uses a provider architecture, so verify paths differ. Test the exact steps on the target version to avoid surprises.
Verification Checklist
- Reproduce the issue on a non‑production host:
openssl version -afollowed by the verification command. Confirm the error code matches the table. - Compare modulus MD5 hashes of leaf and key; identical digests indicate a correct pairing.
- Validate TLS trust with
openssl s_client -connect host:port -CAfile /path/to/trust.pemand verify the “Verify return code: 0” line.
Summary
Certificate chain verification failures in OpenSSL are usually caused by missing or expired intermediates, key‑certificate mismatches, or purpose mismatches. By systematically checking the chain, dates, and key‑certificate pairing, you can pinpoint the root cause and apply the appropriate fix. Remember to respect version‑specific security settings and avoid expanding trust anchors unnecessarily.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.