# 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`
- **Domain:** nginx
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## 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.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| nginx 1.18.0 | active | — | — |
| nginx 1.20.1 | active | — | — |
| nginx 1.22.0 | active | — | — |
| nginx 1.24.0 | active | — | — |

## Workarounds

1. **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;** (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;
   ```
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.** (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.
   ```

## Dead Ends

- **Set proxy_ssl_verify off;** — Disabling verification entirely bypasses security; it works but is not recommended for production with sensitive data. (50% fail)
- **Use proxy_ssl_trusted_certificate with the upstream's public certificate only** — 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. (70% fail)
- **Regenerate upstream certificate with same CA** — If the CA itself is self-signed and not trusted, regenerating the leaf cert won't fix the trust chain. (80% fail)
