Even after installing the certificate and confirming that the Nginx configuration has no errors, the browser still displays “Not Secure.” This situation can almost always be attributed to a specific cause, but the browser only provides the conclusion, not the reason.
The following 8 causes are listed in order of frequency, with corresponding verification commands for each.
Cause Reference Table
| # | Cause | Quick Indicator |
|---|---|---|
| 1 | HTTP resources present on the page (Mixed Content) | Mixed Content warning in the console |
| 2 | Incomplete certificate chain | -verify_return_error returns a non-zero code |
| 3 | Certificate expired | notAfter date has passed |
| 4 | Domain mismatch | Accessed domain is not in the SAN list |
| 5 | Self-signed or private CA | Issuer equals Subject |
| 6 | Accessing via IP or stale cache | Address bar shows an IP; or CDN cached old content |
| 7 | Incorrect system time | Local time differs from actual time |
| 8 | Certificate revoked or issued by untrusted root | Explicit error message indicates this |
① Mixed Content (Most Common)
# Find http resources on the page
curl -s https://example.com/ | grep -oE 'http://[^"''' )]+' | sort -u
# View only resource tags
curl -s https://example.com/ | grep -oE '(src|href)="http://[^"]+"' | sort -u
The browser console will explicitly identify which URL is causing the issue, which is the fastest way to locate it. Note the distinction: script-type resources are blocked directly, while image-type resources merely cause the lock icon to disappear.
② Incomplete Certificate Chain
# Key: Add -verify_return_error
openssl s_client -connect example.com:443 -servername example.com
-verify_return_error </dev/null 2>/dev/null | grep -i 'verify return'
# Check how many certificates the server returned (should be multiple)
openssl s_client -connect example.com:443 -servername example.com
-showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
# Fix: Use fullchain instead of a single certificate
ssl_certificate /path/fullchain.pem;
A characteristic of this issue is that the browser may display normally (it auto-completes the chain), but other clients and diagnostic tools will report errors. Therefore, you must verify using the commands above rather than relying solely on the browser.
③ Certificate Expired
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null
| openssl x509 -noout -dates
Note a special case: The certificate file was updated but not reloaded, so the old one is still in effect.
# Compare file vs. actually effective certificate
openssl x509 -in /path/fullchain.pem -noout -enddate
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null
| openssl x509 -noout -enddate
# If they differ → reload did not take effect
④ Domain Mismatch
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null
| openssl x509 -noout -ext subjectAltName
Common scenarios: The certificate is signed only for www.example.com, but you are accessing example.com (or vice versa); subdomains are not covered.
⑤ Self-Signed Certificate
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null
| openssl x509 -noout -issuer -subject
# issuer equals subject → self-signed
Self-signed certificates will definitely trigger a “Not Secure” warning in public environments and are suitable only for internal or testing scenarios.
⑥ Access Method or Cache Issues
# Are you accessing via IP? (IP cannot match a domain certificate)
# Confirm if the address bar shows a domain name.
# Did the CDN cache old content?
curl -I https://example.com/ | grep -iE 'age|cache|x-cache|server'
“Accessing via IP” is a very common cause—certificates are issued for domain names, so accessing via an IP will inevitably result in a mismatch.
⑦ Incorrect Local System Time
date
# If the time deviation is too large, even a valid certificate may be judged as "not yet effective" or "expired"
A characteristic of this issue is: Only this machine reports an error, while others work fine.
⑧ Revocation or Untrusted Root
The browser will provide an explicit prompt (stating that the certificate is revoked or untrusted). In this case, the certificate needs to be reissued.
Troubleshooting Order
# One command to get an overview
curl -sSv https://example.com/ 2>&1 | grep -iE 'subject|issuer|TLS|SSL connection|verify'
# Standard check sequence
# 1. Chain integrity
openssl s_client -connect example.com:443 -servername example.com
-verify_return_error </dev/null 2>/dev/null | grep -i 'verify return'
# 2. Validity period
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null
| openssl x509 -noout -dates
# 3. Domain matching
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null
| openssl x509 -noout -ext subjectAltName
# 4. Mixed content
curl -s https://example.com/ | grep -oE 'http://[^"]+' | sort -u
Decision Tree
Shows Not Secure
├─ Console has Mixed Content → ① HTTP resources on page
├─ -verify_return_error is non-0 → ② Incomplete chain, switch to fullchain
├─ notAfter has passed → ③ Expired (check if reload took effect)
├─ Accessed domain not in SAN → ④ Domain mismatch (also check if accessing via IP)
├─ issuer = subject → ⑤ Self-signed
├─ Only this machine reports error → ⑦ Check local system time
├─ Prompt says revoked/untrusted → ⑧ Reissue certificate
└─ All checks pass but still warns
└─ ⑥ Clear cache / Confirm accessing domain not IP
Scenario Walkthrough: Certificate Installed, Browser Still Says Not Secure
Symptom: The certificate has been installed and confirmed that the site can be accessed via encryption, but the browser’s address bar still displays “Not Secure,” with varying warning messages.
- Translate “Not Secure” into a specific cause → Different warnings point to completely different root causes. Without categorization, troubleshooting is impossible. Skipping this step means guessing blindly later.
- First item: Check for unencrypted references in requested resources → The console lists blocked resources directly. This is the quickest way to get a complete list.
- Second item: Strictly validate the certificate chain → Browsers auto-complete chains, making their judgment unreliable. You must use methods that disable auto-completion.
- Third item: Verify if the accessed domain is covered by the certificate → Common cases include the main domain being fine but subdomains missing, or forgetting to include the www variant.
- Fourth item: Confirm system time is correct → Large time deviations cause validity period judgments to fail. This is more common after server migrations.
- Re-verify after eliminating items one by one → Clear the cache and check again to avoid old cache affecting the final result.
# ② Certificate Chain (Return code must be 0)
echo | openssl s_client -connect example.com:443 -servername example.com
-verify_return_error 2>&1 | grep -E 'Verify return code|depth'
# ③ Coverage: Confirm the accessed domain is in the list
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null
| openssl x509 -noout -ext subjectAltName -dates
# ④ System Time and Validity
date
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null
| openssl x509 -noout -startdate -enddate
# ① Check for unencrypted references on the page
curl -s https://example.com/ | grep -oE 'src="http://|href="http://' | head
Root Cause: There is more than one cause for these warnings. In this instance, there were unencrypted resource references on the page. The certificate itself was fine—but because classification wasn’t done first, troubleshooting kept circling around certificate issues.
Two key takeaways:
- Categorize “Not Secure” before troubleshooting; don’t jump straight to checking the certificate. Mixed content, incomplete chains, domain mismatches, and time deviations all produce similar warnings.
- Use strict methods to judge the certificate chain; browsers will auto-complete for you. This prevents misjudgments like “It works fine on my end.”
8 Common Pitfalls
- Relying solely on the browser: It completes chains and uses caches, leading to unreliable conclusions.
- Replacing files without reloading: The old certificate remains in effect.
- Using cert instead of fullchain: Results in an incomplete chain.
- Certificate doesn’t cover the current domain: Especially www vs. main domain, or subdomains.
- Accessing via IP: Certificates are issued for domains, so this inevitably fails.
- Ignoring mixed content: HTTP resources on the page will also trigger warnings.
- Not checking local system time: Suspect this first when only one machine reports an error.
- Clearing CDN cache without verification: Changes made, but users still see old content.
Real Customer Feedback (From Cloud Market Reviews and Consultations for Similar Products)
The following excerpts are taken from real buyer reviews and consultations for similar operations services on Alibaba Cloud / Tencent Cloud / Huawei Cloud Cloud Markets (service providers include our store and competitors, provided here for reference only, not fictional tickets from this site):
10***53 2024-05-24 5.0 Affordable price | Skilled technology | Safe and reliable Genuine SSL certificate
10***34 2020-07-09 5.0 Skilled technology | Patient and professional | Timely reply Good, nice configuration, reasonable price
10***27 2021-01-26 5.0 On-time delivery | Skilled technology | Detailed documentation Easy to use