Modern internet security relies fundamentally on X.509 Public Key Infrastructure (PKI) and Transport Layer Security (TLS). Every secure API endpoint, web application, and mobile backend presents an SSL/TLS certificate during the initial TCP handshake to authenticate its identity and establish encrypted sessions.
However, misconfigured certificate bundles, missing intermediate CA certificates, expired credentials, and wildcard syntax misunderstandings represent some of the most frequent causes of catastrophic production outages and elusive API failures.
This comprehensive engineering guide explains how to decode raw X.509 certificates, validate entire PKI trust chains, configure web servers properly, and troubleshoot real-world TLS errors.
Inspect and decode certificates offline or check live server chains with our free SSL/TLS Certificate Decoder or audit security headers with our HTTP Headers Analyzer.
1. Anatomy of an X.509 Certificate
Standardized by the IETF in RFC 5280, an X.509 v3 certificate is a binary document encoded in ASN.1 DER (Distinguished Encoding Rules) format, commonly converted to text using PEM (Privacy-Enhanced Mail) ASCII armor.
-----BEGIN CERTIFICATE-----
MIIFazCCBFOgAwIBAgIQD/f+8b0L+J9NfJ3QxK... (Base64 ASN.1 DER Data) ...
-----END CERTIFICATE-----
Essential X.509 Certificate Fields
X.509 Certificate
├── Version: 3 (0x02)
├── Serial Number: Unique identifier assigned by the CA
├── Signature Algorithm: e.g., ecdsa-with-SHA256 or sha256WithRSAEncryption
├── Issuer: The CA that digitally signed this certificate (C=US, O=Let's Encrypt, CN=R3)
├── Validity:
│ ├── Not Before: 2026-01-01 00:00:00 UTC
│ └── Not After: 2026-04-01 00:00:00 UTC (Max 398 days per CA/Browser Forum)
├── Subject: Common Name (CN) — Note: Deprecated for routing in favor of SANs
├── Subject Public Key Info:
│ ├── Algorithm: RSA (2048/4096-bit) or EC (secp256r1 / P-256)
│ └── Public Key: Raw public key bytes
└── Extensions (X.509 v3):
├── Subject Alternative Name (SAN): DNS:example.com, DNS:*.example.com, IP:1.2.3.4
├── Basic Constraints: Critical, CA:FALSE (for leaf certificates)
├── Key Usage: Digital Signature, Key Encipherment
├── Extended Key Usage: Server Authentication (1.3.6.1.5.5.7.3.1), Client Auth
├── Authority Information Access (AIA): OCSP URL + CA Issuers (Intermediate download)
└── CRL Distribution Points: Download URI for revocation lists
2. Understanding the PKI Chain of Trust
When an HTTPS client (e.g., Google Chrome, cURL, Python requests, or Node.js fetch) connects to a server, it verifies that the server's certificate is signed by an entity it trusts.
Because root Certificate Authorities store their master private keys securely in offline vaults, they never sign end-entity server certificates directly. Instead, they sign one or more Intermediate CA certificates, which in turn sign your server's Leaf Certificate.
[ Root CA (e.g., ISRG Root X1) ]
└── In OS & Browser Trust Stores (Self-Signed, offline)
│
▼ (signs)
[ Intermediate CA (e.g., R3 / E1) ]
└── MUST be served by the web server in the TLS handshake
│
▼ (signs)
[ Leaf Server Certificate (e.g., api.yourdomain.com) ]
└── Issued specifically for your domain name
3. Diagnosing "Incomplete Certificate Chain" Outages
The single most common SSL misconfiguration is serving only the leaf certificate rather than the full certificate chain.
The Symptom
- Desktop Browsers (Chrome, Edge on Windows/macOS): Connection appears to work fine because desktop OSes cache intermediate certificates locally or dynamically fetch them via AIA Chasing (
Authority Information Access). - Mobile Browsers (iOS Safari, Android Chrome) and Backend API Clients (Node.js, cURL, Python, Go, Java): Connection fails immediately with fatal errors:
SSL_ERROR_UNTRUSTED_ISSUERUNABLE_TO_VERIFY_LEAF_SIGNATUREcertificate verify failed: unable to get local issuer certificate
The Solution: Deploy fullchain.pem
Always bundle the leaf certificate followed by the intermediate CA certificates in your web server configuration:
Nginx Configuration
server {
listen 443 ssl http2;
server_name api.example.com;
# CORRECT: fullchain.pem contains Leaf Cert + Intermediate CA
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# WRONG: cert.pem contains only the leaf certificate!
# ssl_certificate /etc/letsencrypt/live/example.com/cert.pem;
}
Apache 2.4+ Configuration
<VirtualHost *:443>
ServerName api.example.com
SSLEngine on
# In Apache 2.4.8+, SSLCertificateFile takes the full chain bundle
SSLCertificateFile /etc/ssl/certs/fullchain.pem
SSLCertificateKeyFile /etc/ssl/private/privkey.pem
</VirtualHost>
4. Wildcard Certificate Rules (RFC 6125)
Wildcard certificates (*.example.com) provide immense convenience for dynamically scaled microservices and tenant subdomains. However, the RFC 6125 standard enforces strict boundary rules:
| Hostname | Covered by *.example.com? |
Explanation |
|---|---|---|
api.example.com |
YES | Single-level subdomain. |
app.example.com |
YES | Single-level subdomain. |
example.com |
NO | Apex / naked root domain is not covered by *. unless explicitly added as a separate SAN. |
dev.api.example.com |
NO | Wildcards do not span across multiple dots (labels). |
*.*.example.com |
INVALID | Multiple wildcard asterisks are prohibited by all CAs. |
[!TIP] When requesting certificates via Certbot or ACME, always specify both the root domain and the wildcard in your SAN list:
certbot certonly --manual --preferred-challenges dns \ -d "example.com" -d "*.example.com"
5. Locking Down CA Issuance with DNS CAA Records
Certification Authority Authorization (CAA) (standardized in RFC 6844) allows domain owners to publish DNS TXT-like records declaring which Certificate Authorities are authorized to issue certificates for their domains.
Before issuing any certificate, public CAs are legally mandated to perform a DNS CAA lookup on the target domain.
Recommended DNS CAA Record Configuration
Add these DNS resource records to your DNS provider (Cloudflare, Route 53, Google Cloud DNS):
# Permit only Let's Encrypt and DigiCert to issue standard certificates
example.com. IN CAA 0 issue "letsencrypt.org"
example.com. IN CAA 0 issue "digicert.com"
# Permit only Let's Encrypt to issue wildcard certificates (*.example.com)
example.com. IN CAA 0 issuewild "letsencrypt.org"
# Dispatch automated security incident alerts if an unauthorized CA receives a request
example.com. IN CAA 0 iodef "mailto:[email protected]"
Verify your domain's live CAA records instantly using our DNS Lookup Tool.
6. Essential OpenSSL Troubleshooting Commands
You can diagnose SSL/TLS issues from the command line using native OpenSSL utilities:
1. Inspect Live Server Certificate Chain & Protocol
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts
Note: Always pass -servername <domain> to include Server Name Indication (SNI).
2. Verify Certificate Expiration Date from a Remote Server
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
3. Decode Local PEM Certificate File Details
openssl x509 -in cert.pem -text -noout
4. Check Subject Alternative Names (SANs) in Local File
openssl x509 -in cert.pem -noout -ext subjectAltName
5. Verify that Private Key matches Certificate
The public key modulus calculated from both files must produce identical SHA-256 hashes:
openssl x509 -noout -modulus -in cert.pem | openssl sha256
openssl rsa -noout -modulus -in privkey.pem | openssl sha256
7. Production Checklist for Zero-Downtime TLS
- Automate Renewal via ACME: Utilize Certbot, Caddy, or Traefik with automated renewal triggered when 30 days remain on certificate validity.
- Always Serve Full Chains: Validate that
fullchain.pem(leaf + intermediate) is deployed to prevent mobile and API client failures. - Deploy DNS CAA Records: Restrict permissible CAs to prevent unauthorized third parties from acquiring spoofed certificates.
- Enforce Modern TLS Protocols: Enable TLS 1.3 and TLS 1.2 with secure AEAD cipher suites (
TLS_AES_128_GCM_SHA256,ECDHE-ECDSA-AES128-GCM-SHA256). - Set HTTP Strict Transport Security (HSTS): Instruct browsers to automatically upgrade all HTTP traffic to HTTPS:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload - Air-gapped Testing: Validate your PEM certificate files before committing them to production with our SSL/TLS Certificate Decoder.