{
  "id": "grpc/stream-idle-timeout",
  "signature": "UNAVAILABLE: grpc: stream idle timeout reached",
  "signature_zh": "UNAVAILABLE: grpc: 流空闲超时",
  "regex": "UNAVAILABLE: grpc: stream idle timeout reached",
  "domain": "grpc",
  "category": "network_error",
  "subcategory": null,
  "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.",
  "root_cause_type": "generic",
  "root_cause_zh": "流式RPC长时间不活动（没有发送或接收数据），由于空闲超时配置，服务器或客户端关闭了流。",
  "versions": [
    {
      "version": "gRPC Go 1.50+",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "gRPC Python 1.50+",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Nginx gRPC proxy 1.25+",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Setting keepalive time to 0 (disable)",
      "why_fails": "May cause connections to be dropped by network middleboxes that expect periodic traffic.",
      "fail_rate": 0.4,
      "condition": "",
      "sources": []
    },
    {
      "action": "Increasing timeout on server only",
      "why_fails": "Client may still have its own idle timeout that triggers first.",
      "fail_rate": 0.35,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "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}",
      "success_rate": 0.88,
      "how": "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}",
      "condition": "",
      "sources": []
    },
    {
      "action": "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.",
      "success_rate": 0.8,
      "how": "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.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "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}",
    "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."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://grpc.io/docs/guides/keepalive/",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.84,
  "fix_success_rate": 0.78,
  "resolvable": "true",
  "first_seen": "2023-11-12",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}