Guide
Internal file expiry vs external TLS check
Compare checking SSL certificate on server vs browser paths—PEM notAfter on disk against the live handshake strangers see after reload, CDN, and load balancers.
Updated Apr 10, 2026 832 words
To check ssl certificate on server vs browser outcomes, compare filesystem
notAfterwith the certificate presented on the public hostname—not with what your laptop trusts on the LAN.
Internal monitoring excels at catching upcoming renewal deadlines on files you control. External checks answer whether those files reached every TLS terminator, CDN configuration, and SNI binding that customers hit. The gap between the two causes most “we renewed yesterday” incidents.
Security and platform engineers own both views: cron jobs that parse /etc/letsencrypt/live, and synthetic probes from outside the VPC. This guide aligns those signals so alerts mean the same thing to on-call.
You will use OpenSSL locally on the host, then repeat against the public DNS name without VPN split tunneling. Bring serial numbers from both runs; they should match after a successful deploy.
Monitoring vendors sometimes sell file-based agents and external synthetics as one SKU, but the data streams measure different risks. File agents answer whether your automation downloaded PEM bytes. External probes answer whether the internet receives them. Both belong in the architecture diagram, not in competition.
What to check
Separate inventory expiry (what is on disk or in a secrets store) from presentation expiry (what the TCP+TLS stack returns after SNI). Also distinguish trust (chain completeness, hostname match) from dates alone—a future notAfter on an incomplete chain still breaks browsers.
When you check ssl certificate on server vs browser, test the same hostname the browser address bar shows. Internal names like app.internal.local may carry valid corporate certs while app.example.com serves an expired public cert on the load balancer.
Include intermediates in server-side inspection. A leaf PEM fresh on disk but configured without the CA bundle can pass a naive file check while failing externally.
When you check ssl certificate on server vs browser, log the config path the daemon actually references. Symlinks under live directories rotate after ACME while sites-enabled still points at an old archive path. Internal monitoring on the wrong symlink is worse than no monitoring because it silences alerts.
Capture whether a load balancer, service mesh sidecar, or CDN terminates TLS in front of the host you SSH into. Internal checks on the origin never observe edge expiry for customers on orange-cloud or reverse-proxy setups.
Step-by-step
On the server (file and local listener)
Locate the configured path from nginx, Apache, or your ingress manifest:
sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates -serial -subject
If the app terminates TLS locally, probe loopback with the public name as SNI:
echo | openssl s_client -connect 127.0.0.1:443 -servername www.example.com 2>/dev/null \
| openssl x509 -noout -dates -serial
Compare serial numbers between file and loopback. Mismatch means the process has not reloaded or points at a different path.
From outside (browser-equivalent path)
echo | openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts 2>/dev/null \
| openssl x509 -noout -dates -serial -issuer
Run the same from a cloud shell or home network, not only the datacenter jump host.
Browser spot-check
Open the site in Chrome or Firefox, view the certificate, and note Valid until plus the certification path depth. Screenshots help executives; serial numbers help engineers.
curl as a witness
curl -vI --connect-timeout 10 https://www.example.com/ 2>&1 | tee /tmp/curl-tls.log
Search the log for expire date and certificate problem lines. curl uses the OS trust store and rejects expired peers like most API clients.
Run external checks twice after a fix: immediately after reload and again ten minutes later. Autoscaling groups and slow CDN publishes mean the first probe can hit a warm node while a cold node still serves expired material. Two serial confirmations reduce false incident closure.
If your organization uses split-horizon DNS, run external probes from at least one network that uses public resolvers. Your laptop on VPN is an internal check even when you use a browser.
How to read the output
Matching serials everywhere: Disk, loopback, external OpenSSL, and browser should show the same serial when a single terminator serves the name. If disk is new but external is old, the deployment did not reach the public path—reload, sync the load balancer, or fix CDN origin settings.
File fresh, external expired: Classic after ACME success without deploy hooks or when only one node in a cluster reloaded. See Let's Encrypt renewal succeeded but the site still shows expired for the handoff checklist.
Server loopback good, external bad: Often CDN or WAF certificates, or DNS still pointing at a deprecated IP. Internal checks never saw the edge that users reach.
Browser works on VPN only: Split DNS may send employees to an internal VIP with a valid cert while the public anycast pool serves expired material. Always keep an external probe outside corp network.
Inventory shows thirty days left, external shows expired: Often a shadow environment still linked from production DNS. Compare SAN lists as well as dates; the wrong vhost may answer first during SNI negotiation.
Common mistakes
Monitoring only openssl x509 on a file that nothing loads at runtime. Kubernetes secrets updated on disk while ingress controllers cache the old cert until pod restart produce the same symptom.
Assuming browser cache caused the warning. PKIX errors are not fixed by hard refresh unless the server actually changed certificates. Re-verify with OpenSSL serial numbers.
Using -k or corporate TLS inspection roots on internal laptops makes external customers look “fine” to you while the world fails. Test with default trust once.
Treating cloud-managed cert “ACTIVE” in a console as proof HTTPS works. ACM attachment to a listener still needs correct SNI and DNS; validate the handshake.
Relying on package manager post-renew hooks without testing reload semantics on containers. Pods that mount secrets only at boot need restarts, not only renewed files on the backing store.
Publishing internal-only Grafana dashboards to executives without an external customer view. Latency and correctness for staff LAN paths rarely match mobile carrier paths.
When to use automation
File-based cron jobs are necessary but insufficient. Automate external live TLS on production hostnames, including after redirects, and alert when served serial diverges from your expected inventory baseline.
Combine presentation checks with RDAP domain expiry so revalidation and customer trust are not surprised by registrar lapses. Thresholds at 30, 14, 7, and 1 day give time to fix reload gaps before browsers do. ssldays emphasizes what strangers see; wire its results into the same dashboard as internal PEM parsers so one pane shows drift.
Define an explicit drift alert when internal file parsers and external TLS probes disagree for more than one polling interval. That condition is almost always an operational bug, not a monitoring false positive.
During change freezes, continue external checks with heightened sensitivity. Freeze periods correlate with skipped reloads because teams fear risky restarts while certificates still age toward notAfter.
Scenario walkthrough
Consider a nightly job that emails when fullchain.pem on disk has fewer than fourteen days remaining. Engineers renew with ACME, the file updates, and the email stops. Customers still see expired warnings because the CDN edge has not pulled the new secret. An external probe that compares serial numbers would have stayed red until the publish step finished, while the internal job went quiet and misclassified the incident as resolved.
Kubernetes illustrates another gap. cert-manager marks the Certificate resource Ready, and an in-cluster checker reads the secret volume mounted into a debug pod. Production traffic flows through an ingress controller on another node class whose pods were not rolled. External checks catch that asymmetry before social media does, while internal metrics look ceremonially perfect.
Managed databases and caches sometimes expose TLS only on administrative ports checked by internal agents. Product traffic exits through a serverless proxy monitored nowhere. When you check ssl certificate on server vs browser, map ports in the architecture diagram to monitor classes so quiet auxiliary listeners do not lull teams.
Regulated environments may require internal scanners that never leave a compliance enclave. Pair those scans with a single approved external vantage that mirrors customer paths. Auditors appreciate dual evidence, and operators catch split-horizon mistakes early.
Executive dashboards that aggregate only internal data should carry a visible disclaimer that customer impact is validated elsewhere. Clarity prevents the awkward board question about why uptime charts stayed green during a certificate fire drill that customers actually felt.
Choosing check frequency
Internal file parsers can run hourly without upsetting anyone; they read local disks cheaply. External synthetics cost more and should target customer-visible names at intervals your SLA documents. Align frequencies so neither side is the orphan: if external checks run daily only, do not page on internal hourly noise unless drift persists across two external failures.
Document which hostnames are exempt from external checks because they live on private networks. Exempt lists need quarterly review so forgotten public DNS records do not leave stranded names.
For check ssl certificate on server vs browser, include mobile carrier and residential ISP vantage when budgets allow. Corporate-only external monitors miss consumer pain that dominates app store reviews.
Game-day exercises rotate engineers through both internal and external consoles so muscle memory exists for sev-1 bridges. Reading-only access to external monitors prevents “permission denied” delays at the worst moment.
When decommissioning hosts, remove them from internal file monitors and external hostname lists the same day. Ghost alerts desensitize teams and hide real drift on neighbor services.
Partner APIs that pin certificates may need contractual notification when your external serial changes. Internal renew jobs complete silently unless integration teams track presentation impacts.
Blue-green deploys should fail closed if external checks on green diverge from internal inventory while traffic weights shift. Partial cutovers with mismatched serials are worse than delaying the switch one hour.
Observability vendors selling log scrapers are not substitutes for handshake monitors. Logs may show HTTP 200 while TLS is already broken for new sessions when terminate-proxy quirks exist.
Frequently asked questions
Why does `openssl` on the server show a good date while Chrome fails?
You may have queried the wrong file, wrong SNI, or loopback while public DNS hits another tier. Capture external -showcerts and compare SANs and chain length to the browser error.
Are CT logs a substitute for external checks?
Certificate Transparency proves issuance, not that your listener presents that cert. Use CT for audit; use live probes for operations.
Do I need both checks if I use a managed CDN certificate?
Yes—origin and edge certificates differ. Internal files may track origin while customers see the CDN edge expiry. Monitor each name in the chain users actually negotiate.
How often should internal and external agree?
Continuously for production hostnames. After every renewal or infra change, run both until serials match from at least two external vantage points.
See what the server presents right now
Free live certificate check — no signup.