{"record":{"id":"6a3a457f6d62d649","repo":"hashicorp/nomad","slug":"failed-to-parse-x-nomad-lastcontact-v","errorCode":null,"errorMessage":"Failed to parse X-Nomad-LastContact: %v","messagePattern":"Failed to parse X-Nomad-LastContact: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/api.go","lineNumber":1194,"sourceCode":"\t}\n\treturn wm, nil\n}\n\n// parseQueryMeta is used to help parse query meta-data\nfunc parseQueryMeta(resp *http.Response, q *QueryMeta) error {\n\theader := resp.Header\n\n\t// Parse the X-Nomad-Index\n\tindex, err := strconv.ParseUint(header.Get(\"X-Nomad-Index\"), 10, 64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failed to parse X-Nomad-Index: %v\", err)\n\t}\n\tq.LastIndex = index\n\n\t// Parse the X-Nomad-LastContact\n\tlast, err := strconv.ParseUint(header.Get(\"X-Nomad-LastContact\"), 10, 64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failed to parse X-Nomad-LastContact: %v\", err)\n\t}\n\tif last > math.MaxInt64 {\n\t\treturn fmt.Errorf(\"Last contact duration is out of range: %d\", last)\n\t}\n\tq.LastContact = time.Duration(last) * time.Millisecond\n\tq.NextToken = header.Get(\"X-Nomad-NextToken\")\n\n\t// Parse the X-Nomad-KnownLeader\n\tswitch header.Get(\"X-Nomad-KnownLeader\") {\n\tcase \"true\":\n\t\tq.KnownLeader = true\n\tdefault:\n\t\tq.KnownLeader = false\n\t}\n\treturn nil\n}\n\n// parseWriteMeta is used to help parse write meta-data","sourceCodeStart":1176,"sourceCodeEnd":1212,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/api/api.go#L1176-L1212","documentation":"The Nomad API client parses the X-Nomad-LastContact response header as a uint64 millisecond duration when decoding query metadata (parseQueryMeta). If the header is missing, empty, or not a valid unsigned integer, strconv.ParseUint fails and this error wraps the underlying parse error. It indicates the server response (or an intermediate proxy) did not supply a well-formed LastContact header.","triggerScenarios":"Calling any blocking-query API method (e.g. jobs.List, nodes.List, QueryOptions-based calls) when the X-Nomad-LastContact header is absent, empty, or non-numeric — typically from a proxy/gateway stripping headers or a non-Nomad server responding.","commonSituations":"Requests routed through reverse proxies or load balancers that drop X-Nomad-* headers; pointing the client at a non-Nomad HTTP endpoint; intercepted/mocked responses in tests lacking the header.","solutions":["Check what server actually responded: curl -v the endpoint and inspect the X-Nomad-LastContact header","Remove or fix proxy/load-balancer config that strips X-Nomad-* headers","Verify the client is pointed at a real Nomad agent HTTP endpoint (default port 4646)","Upgrade the Nomad agent/client if versions are mismatched"],"exampleFix":"// before\nc.Error = httpResp.Header.Get(\"X-Nomad-LastContact\") // empty through proxy\n// after\nproxy_pass_headers X-Nomad-LastContact; // nginx: forward X-Nomad-* headers","handlingStrategy":"validation","validationCode":"resp, _ := http.Get(url)\nif v := resp.Header.Get(\"X-Nomad-LastContact\"); v == \"\" {\n    if _, err := strconv.ParseUint(v, 10, 64); err != nil {\n        return fmt.Errorf(\"server did not return a valid X-Nomad-LastContact header\")\n    }\n}","typeGuard":"func hasValidLastContact(h http.Header) bool {\n    _, err := strconv.ParseUint(h.Get(\"X-Nomad-LastContact\"), 10, 64)\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Ensure proxies/load balancers forward X-Nomad-* headers","Point clients only at real Nomad agent HTTP endpoints","Add integration tests asserting query metadata headers are present"],"tags":["http-header","parsing","nomad-api"],"backgroundTag":"http-header-parse-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"}