{"record":{"id":"f0199217ce2a520f","repo":"hashicorp/nomad","slug":"unable-to-unmarshal-response-with-status-d-v","errorCode":null,"errorMessage":"unable to unmarshal response with status %d: %v","messagePattern":"unable to unmarshal response with status (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/agent.go","lineNumber":285,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar health AgentHealthResponse\n\t_, resp, err := a.client.doRequest(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\t// Always try to decode the response as JSON\n\terr = json.NewDecoder(resp.Body).Decode(&health)\n\tif err == nil {\n\t\treturn &health, nil\n\t}\n\n\t// Return custom error when response is not expected JSON format\n\treturn nil, fmt.Errorf(\"unable to unmarshal response with status %d: %v\", resp.StatusCode, err)\n}\n\n// Host returns debugging context about the agent's host operating system\nfunc (a *Agent) Host(serverID, nodeID string, q *QueryOptions) (*HostDataResponse, error) {\n\tif q == nil {\n\t\tq = &QueryOptions{}\n\t}\n\tif q.Params == nil {\n\t\tq.Params = make(map[string]string)\n\t}\n\n\tif serverID != \"\" {\n\t\tq.Params[\"server_id\"] = serverID\n\t}\n\n\tif nodeID != \"\" {\n\t\tq.Params[\"node_id\"] = nodeID\n\t}","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/api/agent.go#L267-L303","documentation":"In Nomad's Go API client (api/agent.go:285), Agent.Health decodes the HTTP response body into a health struct; when json decoding fails, it returns this error embedding the HTTP status code and the underlying decode error. It means the server responded, but the body was not the expected JSON (or the stream was empty/truncated). It is a client-side wrap of a JSON decode failure, not a transport error.","triggerScenarios":"Calling (a *Agent).Health(serverID, region string) when the Nomad agent returns a non-JSON body: an HTML error page from a reverse proxy/load balancer, an empty body with 200, a proxy 502/503 page, or a truncated response.","commonSituations":"Hitting Nomad through an nginx/ALB that intercepts the request and serves its own HTML error page; pointing NOMAD_ADDR at a non-Nomad HTTP service; a proxy closing the connection mid-body; TLS-terminating proxy returning a plain-text error with 200.","solutions":["Check resp.StatusCode embedded in the message; if it is not 200, fix the proxy/routing so requests actually reach the Nomad agent","curl the Health endpoint directly (e.g. curl -v $NOMAD_ADDR/v1/agent/health) and inspect the raw body to see what is actually returned","Verify NOMAD_ADDR points at a Nomad agent HTTP port and not a UI or unrelated service","If behind a load balancer, configure it to pass through Nomad endpoints rather than serving HTML error pages","Retry on transient truncation; investigate the wrapped %v decode error for the exact JSON offset/problem"],"exampleFix":"// before: transparent proxy returns HTML 502, decode fails\nhealth, err := agent.Health(\"\", \"\")\n// after: check status via a raw query first and fail fast with a clearer message\nresp, err := a.client.rawQuery(\"/v1/agent/health\", nil, nil)\nif err != nil { return nil, err }\nif resp.StatusCode != http.StatusOK {\n    return nil, fmt.Errorf(\"agent health endpoint returned status %d; check proxy/routing\", resp.StatusCode)\n}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(cfg.Address)\nif err != nil || u.Host == \"\" { return fmt.Errorf(\"NOMAD_ADDR %q does not look like a Nomad server\", cfg.Address) }","typeGuard":"func isJSONContentType(h http.Header) bool {\n\treturn strings.Contains(h.Get(\"Content-Type\"), \"application/json\")\n}","tryCatchPattern":"health, err := agent.Health(\"\", \"\")\nif err != nil {\n\tvar serr *json.SyntaxError\n\tif errors.As(err, &serr) || strings.Contains(err.Error(), \"unable to unmarshal\") {\n\t\treturn fmt.Errorf(\"non-JSON response from agent; check proxy/routing: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Point the client directly at Nomad, not through HTML-error-page-serving proxies","Sanity-check the endpoint with curl before wiring up the client","Log the status code embedded in the message to distinguish proxy pages from decode bugs"],"tags":["json","http","nomad-api"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}