# UNAVAILABLE: grpc: TLS handshake failed: certificate has expired

- **ID:** `grpc/tls-certificate-expiration`
- **Domain:** grpc
- **Category:** auth_error
- **Error Code:** `GRPC_TLS_CERT_EXPIRED`
- **Verification:** ai_generated
- **Fix Rate:** 96%

## Root Cause

The TLS certificate used by the gRPC server (or client in mutual TLS) has passed its expiry date, causing the handshake to fail.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| gRPC v1.48.x | active | — | — |
| gRPC v1.58.x | active | — | — |
| gRPC v1.64.x | active | — | — |

## Workarounds

1. **Renew the TLS certificate: generate a new certificate with `openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -days 365 -nodes`, then restart the gRPC server with the new files.** (96% success)
   ```
   Renew the TLS certificate: generate a new certificate with `openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -days 365 -nodes`, then restart the gRPC server with the new files.
   ```
2. **If using Let's Encrypt, run `certbot renew` to automatically renew certificates, then reload the gRPC server (e.g., `kill -HUP <pid>` or restart the process).** (90% success)
   ```
   If using Let's Encrypt, run `certbot renew` to automatically renew certificates, then reload the gRPC server (e.g., `kill -HUP <pid>` or restart the process).
   ```
3. **As a temporary emergency fix, set the system clock back to within the certificate's validity period (not recommended for production), then restart the server.** (60% success)
   ```
   As a temporary emergency fix, set the system clock back to within the certificate's validity period (not recommended for production), then restart the server.
   ```

## Dead Ends

- **** — This bypasses hostname verification but not certificate expiration; the handshake still fails because the certificate itself is invalid. (80% fail)
- **** — SSL session caching affects performance, not certificate validation; expiration is checked during full handshake. (50% fail)
- **** — The expired certificate remains the same; restarting does not fix the expiration date. (90% fail)
