# INTERNAL: panic caught in unary client interceptor: runtime error: invalid memory address or nil pointer dereference

- **ID:** `grpc/client-interceptor-panic-recovery`
- **Domain:** grpc
- **Category:** runtime_error
- **Error Code:** `GRPC_INTERNAL_PANIC_INTERCEPTOR`
- **Verification:** ai_generated
- **Fix Rate:** 85%

## Root Cause

A client-side interceptor panicked due to a nil pointer dereference, which was recovered by gRPC's internal recovery interceptor but not properly handled upstream.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| gRPC-go v1.63.0 | active | — | — |
| gRPC-java v1.62.0 | active | — | — |
| envoy v1.29.0 | active | — | — |

## Workarounds

1. **Add explicit nil checks before dereferencing context values in the interceptor. For example, in Go: if md, ok := metadata.FromIncomingContext(ctx); ok { ... } else { return nil, status.Error(codes.Internal, "missing metadata") }** (90% success)
   ```
   Add explicit nil checks before dereferencing context values in the interceptor. For example, in Go: if md, ok := metadata.FromIncomingContext(ctx); ok { ... } else { return nil, status.Error(codes.Internal, "missing metadata") }
   ```
2. **Wrap the interceptor with a custom recovery middleware that converts panics to gRPC errors with stack traces: use grpc_recovery.UnaryServerInterceptor() from go-grpc-middleware.** (85% success)
   ```
   Wrap the interceptor with a custom recovery middleware that converts panics to gRPC errors with stack traces: use grpc_recovery.UnaryServerInterceptor() from go-grpc-middleware.
   ```
3. **Upgrade to gRPC v1.64.0+ which includes improved panic recovery in interceptors, and enable verbose logging with GRPC_GO_LOG_SEVERITY_LEVEL=info to capture stack traces.** (75% success)
   ```
   Upgrade to gRPC v1.64.0+ which includes improved panic recovery in interceptors, and enable verbose logging with GRPC_GO_LOG_SEVERITY_LEVEL=info to capture stack traces.
   ```

## Dead Ends

- **** — Restarting the client process without fixing the interceptor code will cause the same panic on the next request. (95% fail)
- **** — Adding a generic recovery handler at the application level that logs but returns a generic error masks the root cause, leading to silent data corruption. (85% fail)
- **** — Disabling all interceptors removes tracing and auth, but the underlying nil pointer might still exist in the call path. (70% fail)
