# upstream SSL certificate verify failed: self-signed certificate in certificate chain

- **ID:** `nginx/proxy-pass-https-backend-certificate-verify-failed`
- **Domain:** nginx
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

Nginx's proxy_pass to an HTTPS upstream fails because the upstream's SSL certificate is self-signed or signed by an untrusted CA, and nginx's default SSL verification rejects it.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| nginx 1.20.x | active | — | — |
| nginx 1.22.x | active | — | — |
| nginx 1.24.x | active | — | — |

## Workarounds

1. **Configure nginx to trust the upstream's self-signed certificate by specifying the CA file in proxy_ssl_trusted_certificate. Example:
location / {
    proxy_pass https://upstream.example.com;
    proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.crt;
    proxy_ssl_verify on;
    proxy_ssl_verify_depth 2;
}** (95% success)
   ```
   Configure nginx to trust the upstream's self-signed certificate by specifying the CA file in proxy_ssl_trusted_certificate. Example:
location / {
    proxy_pass https://upstream.example.com;
    proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.crt;
    proxy_ssl_verify on;
    proxy_ssl_verify_depth 2;
}
   ```
2. **Use proxy_ssl_verify off only in development environments with a clear comment that it is insecure.** (85% success)
   ```
   Use proxy_ssl_verify off only in development environments with a clear comment that it is insecure.
   ```
3. **If the upstream uses a corporate CA, download the CA certificate and place it in /etc/nginx/ssl/, then reference it as above.** (90% success)
   ```
   If the upstream uses a corporate CA, download the CA certificate and place it in /etc/nginx/ssl/, then reference it as above.
   ```

## Dead Ends

- **** — While it bypasses the error, it exposes the connection to man-in-the-middle attacks. (95% fail)
- **** — Nginx uses its own CA bundle specified by proxy_ssl_trusted_certificate, not the system store by default. (75% fail)
- **** — The certificate itself is unchanged; nginx still rejects it. (90% fail)
