nginx
auth_error
ai_generated
true
SSL: certificate verify failed: self-signed certificate in certificate chain while SSL handshaking to upstream
ID: nginx/ssl-certificate-verify-failed-self-signed-certificate-in-chain
80%Fix Rate
86%Confidence
1Evidence
2023-09-20First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| nginx 1.18.0 | active | — | — | — |
| nginx 1.20.1 | active | — | — | — |
| nginx 1.22.0 | active | — | — | — |
| nginx 1.24.0 | active | — | — | — |
Root Cause
Upstream server uses a self-signed certificate or a chain ending in a self-signed root, and nginx proxy_ssl_verify is enabled without the proper CA certificate.
generic中文
上游服务器使用了自签名证书或链以自签名根证书结尾,并且 nginx 启用了 proxy_ssl_verify 但未配置正确的 CA 证书。
Official Documentation
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verifyWorkarounds
-
85% success Obtain the upstream's self-signed CA certificate and configure proxy_ssl_trusted_certificate with that CA file, then enable proxy_ssl_verify. Example: proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.crt; proxy_ssl_verify on; proxy_ssl_verify_depth 2;
Obtain the upstream's self-signed CA certificate and configure proxy_ssl_trusted_certificate with that CA file, then enable proxy_ssl_verify. Example: proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.crt; proxy_ssl_verify on; proxy_ssl_verify_depth 2;
-
90% success Replace the upstream's self-signed certificate with one signed by a public CA (e.g., Let's Encrypt). This eliminates the need for custom trust configuration.
Replace the upstream's self-signed certificate with one signed by a public CA (e.g., Let's Encrypt). This eliminates the need for custom trust configuration.
中文步骤
Obtain the upstream's self-signed CA certificate and configure proxy_ssl_trusted_certificate with that CA file, then enable proxy_ssl_verify. Example: proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.crt; proxy_ssl_verify on; proxy_ssl_verify_depth 2;
Replace the upstream's self-signed certificate with one signed by a public CA (e.g., Let's Encrypt). This eliminates the need for custom trust configuration.
Dead Ends
Common approaches that don't work:
-
Set proxy_ssl_verify off;
50% fail
Disabling verification entirely bypasses security; it works but is not recommended for production with sensitive data.
-
Use proxy_ssl_trusted_certificate with the upstream's public certificate only
70% fail
If the upstream has a full chain, nginx needs the root CA, not just the leaf cert. The leaf cert alone may not establish trust.
-
Regenerate upstream certificate with same CA
80% fail
If the CA itself is self-signed and not trusted, regenerating the leaf cert won't fix the trust chain.