{"record":{"id":"59907bc837f22d8d","repo":"t8y2/dbx","slug":"etcd-v2-probe-against-s-failed-http-d-s","errorCode":null,"errorMessage":"etcd v2 probe against %s failed: HTTP %d %s","messagePattern":"etcd v2 probe against (.+?) failed: HTTP (.+?) (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/etcd2-go/client.go","lineNumber":272,"sourceCode":"// PERMISSION_DENIED handling for restricted users.\nfunc (c *authenticatedClient) probeV2(ctx context.Context) (map[string]any, error) {\n\tresponse, err := c.request(ctx, http.MethodGet, \"/v2/members\", \"\", nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer drainClose(response.Body)\n\tswitch response.StatusCode {\n\tcase http.StatusOK:\n\t\treturn map[string]any{\"ok\": true, \"endpoint\": c.endpoint}, nil\n\tcase http.StatusForbidden:\n\t\treturn map[string]any{\"ok\": true, \"endpoint\": c.endpoint, \"limited\": true}, nil\n\tcase http.StatusNotFound:\n\t\treturn nil, fmt.Errorf(\"ETCD_V2_API_DISABLED: %s does not expose the etcd v2 API (removed in etcd 3.6+)\", c.endpoint)\n\tcase http.StatusUnauthorized:\n\t\treturn nil, fmt.Errorf(\"ETCD_UNAUTHENTICATED: authentication failed against %s\", c.endpoint)\n\tdefault:\n\t\tbody, _ := io.ReadAll(io.LimitReader(response.Body, 4096))\n\t\treturn nil, fmt.Errorf(\"etcd v2 probe against %s failed: HTTP %d %s\", c.endpoint, response.StatusCode, strings.TrimSpace(string(body)))\n\t}\n}\n\n// do performs a v2 API request and returns the body. Non-2xx responses are\n// converted into etcdError values carrying the server's errorCode/message.\nfunc (c *authenticatedClient) do(ctx context.Context, method, path, body string, header map[string]string) ([]byte, *http.Response, error) {\n\tresponse, err := c.request(ctx, method, path, body, header)\n\tif err != nil {\n\t\treturn nil, response, err\n\t}\n\tpayload, readErr := io.ReadAll(response.Body)\n\t_ = response.Body.Close()\n\tif response.StatusCode < 200 || response.StatusCode >= 300 {\n\t\treturn nil, response, errorFromResponse(response.StatusCode, payload)\n\t}\n\tif readErr != nil {\n\t\treturn nil, response, readErr\n\t}","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/etcd2-go/client.go#L254-L290","documentation":"This is the fallback error from probeV2: the v2 API endpoint returned an HTTP status other than 200, 403, 404, or 401. The message includes the status code and up to 4KB of the response body so the underlying server-side failure is visible. It wraps whatever non-happy-path HTTP response the probe got.","triggerScenarios":"probeClient receives statuses like 500 (etcd panics/overloaded), 503 (no leader / cluster unavailable), 400, or a proxy's HTML error page on the v2 probe request.","commonSituations":"etcd cluster without a leader (post-failure election), reverse proxy or load balancer returning 502/503, etcd still starting up, TLS-terminating proxy misrouting the request.","solutions":["Read the HTTP status and body in the message to identify the server-side cause.","Check cluster health: etcdctl endpoint health / endpoint status; look for 'no leader' or low quorum.","If a proxy sits in front of etcd, bypass it or fix its routing/health checks for port 2379.","Retry after the cluster recovers; this condition is often transient."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Get(endpoint + \"/health\")\nif err != nil || resp.StatusCode != http.StatusOK { return fmt.Errorf(\"endpoint not healthy, aborting probe\") }","typeGuard":null,"tryCatchPattern":"err := probeClient(ctx, cfg)\nif err != nil && strings.Contains(err.Error(), \"failed: HTTP 5\") {\n    return retryWithBackoff(ctx, 3, probeClient, cfg) // transient 5xx\n}","preventionTips":["Check etcdctl endpoint health before probing","Bypass or correctly configure proxies in front of etcd","Use exponential backoff — 503 during leader election is common"],"tags":["etcd","http","probe"],"backgroundTag":"http-server-error","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}