# UNAVAILABLE: grpc: stream idle timeout reached

- **ID:** `grpc/stream-idle-timeout`
- **Domain:** grpc
- **Category:** network_error
- **Verification:** ai_generated
- **Fix Rate:** 78%

## Root Cause

A streaming RPC has been inactive for too long (no data sent or received) and the server or client closes the stream due to idle timeout configuration.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| gRPC Go 1.50+ | active | — | — |
| gRPC Python 1.50+ | active | — | — |
| Nginx gRPC proxy 1.25+ | active | — | — |

## Workarounds

1. **Send periodic keepalive pings from client. In Go: grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: 30 * time.Second, Timeout: 10 * time.Second}). Set server: keepalive.ServerParameters{MaxConnectionIdle: 5 * time.Minute}** (88% success)
   ```
   Send periodic keepalive pings from client. In Go: grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: 30 * time.Second, Timeout: 10 * time.Second}). Set server: keepalive.ServerParameters{MaxConnectionIdle: 5 * time.Minute}
   ```
2. **Use bidirectional streaming with periodic heartbeat messages. In Python: every 10 seconds send a small protobuf message (e.g., Empty) from client and have server echo it back.** (80% success)
   ```
   Use bidirectional streaming with periodic heartbeat messages. In Python: every 10 seconds send a small protobuf message (e.g., Empty) from client and have server echo it back.
   ```

## Dead Ends

- **Setting keepalive time to 0 (disable)** — May cause connections to be dropped by network middleboxes that expect periodic traffic. (40% fail)
- **Increasing timeout on server only** — Client may still have its own idle timeout that triggers first. (35% fail)
