{
  "id": "communication/grpc-unavailable-no-healthy-upstream",
  "signature": "grpc::UNAVAILABLE: No healthy upstream endpoints",
  "signature_zh": "grpc::UNAVAILABLE：没有健康的上游端点",
  "regex": "grpc::UNAVAILABLE.*No healthy upstream",
  "domain": "communication",
  "category": "network_error",
  "subcategory": null,
  "root_cause": "gRPC client fails to connect because the load balancer or service registry reports zero healthy backends for the target service.",
  "root_cause_type": "generic",
  "root_cause_zh": "gRPC 客户端无法连接，因为负载均衡器或服务注册中心报告目标服务没有健康的后端实例。",
  "versions": [
    {
      "version": "gRPC 1.48",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Envoy 1.26",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Kubernetes 1.28",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Istio 1.18",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Restart the client application to force a new connection",
      "why_fails": "Restarting the gRPC client does not fix the root cause of unhealthy backends; the client will re-encounter the same error until the backend pool recovers.",
      "fail_rate": 0.95,
      "condition": "",
      "sources": []
    },
    {
      "action": "Disable TLS/SSL on the gRPC channel",
      "why_fails": "Disabling TLS removes encryption but does not address backend health; the error stems from upstream unavailability, not protocol negotiation.",
      "fail_rate": 0.85,
      "condition": "",
      "sources": []
    },
    {
      "action": "Change the target port to 443 or another arbitrary number",
      "why_fails": "Changing to a random port bypasses the correct service endpoint, making the situation worse by connecting to a non-existent service.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Verify backend health via `kubectl get endpoints -n <namespace> <service-name>` or equivalent service registry query. Then restart unhealthy pods: `kubectl rollout restart deployment/<deployment-name> -n <namespace>`.",
      "success_rate": 0.75,
      "how": "Verify backend health via `kubectl get endpoints -n <namespace> <service-name>` or equivalent service registry query. Then restart unhealthy pods: `kubectl rollout restart deployment/<deployment-name> -n <namespace>`.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Add a retry with backoff in the gRPC client using a middleware like `grpc_retry` in Go: `import \"github.com/grpc-ecosystem/go-grpc-middleware/retry\"; opts := []grpc_retry.CallOption{grpc_retry.WithMax(3), grpc_retry.WithBackoff(grpc_retry.BackoffLinear(100 * time.Millisecond))}`",
      "success_rate": 0.7,
      "how": "Add a retry with backoff in the gRPC client using a middleware like `grpc_retry` in Go: `import \"github.com/grpc-ecosystem/go-grpc-middleware/retry\"; opts := []grpc_retry.CallOption{grpc_retry.WithMax(3), grpc_retry.WithBackoff(grpc_retry.BackoffLinear(100 * time.Millisecond))}`",
      "condition": "",
      "sources": []
    },
    {
      "action": "Increase the readiness probe threshold in the Kubernetes deployment spec: `readinessProbe.periodSeconds: 10` and `failureThreshold: 5` to allow slower-starting backends more time to become healthy.",
      "success_rate": 0.65,
      "how": "Increase the readiness probe threshold in the Kubernetes deployment spec: `readinessProbe.periodSeconds: 10` and `failureThreshold: 5` to allow slower-starting backends more time to become healthy.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Verify backend health via `kubectl get endpoints -n <namespace> <service-name>` or equivalent service registry query. Then restart unhealthy pods: `kubectl rollout restart deployment/<deployment-name> -n <namespace>`.",
    "Add a retry with backoff in the gRPC client using a middleware like `grpc_retry` in Go: `import \"github.com/grpc-ecosystem/go-grpc-middleware/retry\"; opts := []grpc_retry.CallOption{grpc_retry.WithMax(3), grpc_retry.WithBackoff(grpc_retry.BackoffLinear(100 * time.Millisecond))}`",
    "Increase the readiness probe threshold in the Kubernetes deployment spec: `readinessProbe.periodSeconds: 10` and `failureThreshold: 5` to allow slower-starting backends more time to become healthy."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://grpc.io/docs/guides/error-handling/",
  "official_doc_section": null,
  "error_code": "UNAVAILABLE",
  "verification_tier": "ai_generated",
  "confidence": 0.88,
  "fix_success_rate": 0.82,
  "resolvable": "partial",
  "first_seen": "2023-06-15",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}