The browser doesn't trust the certificate as presented: it's self-signed, issued by an untrusted CA, or (the sneaky one) the intermediate chain is missing. The fix differs per cause.
Legit inside companies: install the internal CA on clients, or issue per-service certs from your CA. For public sites, use Let's Encrypt/Cloudflare Origin CA instead.
You installed only the leaf cert. Browsers with AIA fetching hide it; Android, curl, Python, and Java fail. openssl s_client -connect host:443 -showcerts | grep -c 'BEGIN CERT' — 1 means chain problem.
A valid-looking leaf chained to an intermediate that itself is untrusted/expired — same error, check the -issuer chain.
openssl s_client -connect your.host:443 -servername your.host -showcerts </dev/null 2>/dev/null | grep -E 's:|i:'
# nginx: ssl_certificate /etc/letsencrypt/live/your.host/fullchain.pem # NOT cert.pem
# macOS: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.pem ; Linux: /usr/local/share/ca-certificates + update-ca-certificates
sudo certbot --nginx -d your.host # 5 minutes, auto-renewing, kills this error for everyone
The fullchain-vs-leaf mistake is the #1 cause of 'works on desktop, breaks on mobile/API' cert errors. SSL Labs (ssllabs.com/ssltest) grades the served chain — chain-incomplete shows immediately.
Chrome fetches missing intermediates (AIA); Android doesn't. Your server serves only the leaf. Fix: configure fullchain.pem (leaf + intermediates) — correct everywhere.
For internal tooling with the CA deliberately trusted on clients, yes. For anything public or team-wide without that trust story, use Let's Encrypt or your provider's managed TLS.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.