# Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="failed to connect to all addresses; last error: UNKNOWN: Failed SSL handshake")

- **ID:** `dotnet/grpc-ssl-handshake-failed`
- **Domain:** dotnet
- **Category:** network_error
- **Verification:** ai_generated
- **Fix Rate:** 82%

## Root Cause

gRPC client fails SSL/TLS handshake with server due to mismatched protocols, missing or invalid certificates, or server not supporting HTTP/2 over TLS.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| .NET 6.0 | active | — | — |
| .NET 7.0 | active | — | — |
| .NET 8.0 | active | — | — |
| Grpc.Net.Client 2.49 | active | — | — |
| Grpc.Net.Client 2.52 | active | — | — |

## Workarounds

1. **Ensure server certificate is trusted by client machine. Install the server's CA certificate using certmgr.msc or update Linux CA store.** (85% success)
   ```
   Ensure server certificate is trusted by client machine. Install the server's CA certificate using certmgr.msc or update Linux CA store.
   ```
2. **Configure gRPC client to use specific TLS version: AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); and set HttpClientHandler.SslProtocols = SslProtocols.Tls12;** (80% success)
   ```
   Configure gRPC client to use specific TLS version: AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); and set HttpClientHandler.SslProtocols = SslProtocols.Tls12;
   ```
3. **If using .NET Core 3.1+ and server uses self-signed cert, add client code: var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; (not for production).** (95% success)
   ```
   If using .NET Core 3.1+ and server uses self-signed cert, add client code: var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; (not for production).
   ```

## Dead Ends

- **Disable SSL validation entirely by setting ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }** — Disabling SSL validation creates a severe security vulnerability and may not fix protocol-level mismatches like TLS version or cipher suite. (90% fail)
- **Use HTTP/1.1 instead of HTTP/2** — gRPC requires HTTP/2; switching to HTTP/1.1 will cause protocol errors and the gRPC call will fail with a different error. (95% fail)
- **Set AppContext switch to ignore certificate revocation** — Ignoring revocation does not address root cause of handshake failure (e.g., mismatched cipher suites or expired certificate). (85% fail)
