{"record":{"id":"96e4c9a016d68ea2","repo":"hashicorp/nomad","slug":"failed-to-parse-x-nomad-index-v","errorCode":null,"errorMessage":"Failed to parse X-Nomad-Index: %v","messagePattern":"Failed to parse X-Nomad-Index: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/api.go","lineNumber":1187,"sourceCode":"\twm := &WriteMeta{RequestTime: rtt}\n\tparseWriteMeta(resp, wm)\n\n\tif out != nil {\n\t\tif err := decodeBody(resp, &out); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\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","sourceCodeStart":1169,"sourceCodeEnd":1205,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/api/api.go#L1169-L1205","documentation":"In api/api.go:1187, parseQueryMeta reads blocking-query metadata from response headers; X-Nomad-Index must parse as a uint64. If the header is absent, empty, or non-numeric, the client returns this error. This indicates the response did not come from a genuine Nomad server endpoint (proxies, mocks, or non-Nomad services often omit it).","triggerScenarios":"Any blocking-query list/read call (Nodes().List, Jobs().Info, etc.) where the response lacks a valid X-Nomad-Index header — non-Nomad upstream, misconfigured proxy stripping headers, or test double returning plain responses.","commonSituations":"Pointing the client at a service mesh/gateway that strips X-Nomad-* headers; using a stub server in tests without the header; old/incompatible server versions; hitting the UI route instead of the API.","solutions":["Verify requests reach a real Nomad server: curl -si $NOMAD_ADDR/v1/nodes and check X-Nomad-Index is present","Remove/fix proxies that strip X-Nomad-* headers, or re-add them via the proxy","Check you are hitting /v1 API paths, not the web UI","In tests, use the Nomad test server or add the header: w.Header().Set(\"X-Nomad-Index\", \"100\")","Confirm client and server versions are compatible"],"exampleFix":"// before: mock handler returns JSON without headers\nw.Write([]byte(`{\"Nodes\":[]}`))\n// after\nw.Header().Set(\"X-Nomad-Index\", \"100\")\nw.Header().Set(\"X-Nomad-KnownLeader\", \"true\")\nw.Write([]byte(`{\"Nodes\":[]}`))","handlingStrategy":"validation","validationCode":"resp, err := http.Get(cfg.Address + \"/v1/nodes\")\nif err != nil { return err }\nif resp.Header.Get(\"X-Nomad-Index\") == \"\" {\n\treturn errors.New(\"upstream is not a Nomad server (missing X-Nomad-Index)\")\n}","typeGuard":"func hasNomadMeta(h http.Header) bool {\n\t_, err := strconv.ParseUint(h.Get(\"X-Nomad-Index\"), 10, 64)\n\treturn err == nil\n}","tryCatchPattern":"_, qm, err := client.Nodes().List(nil)\nif err != nil && strings.Contains(err.Error(), \"X-Nomad-Index\") {\n\treturn fmt.Errorf(\"responses lack Nomad metadata; check proxy header stripping / non-Nomad upstream: %w\", err)\n}","preventionTips":["Verify proxies preserve X-Nomad-* headers","In tests, add X-Nomad-Index to mock responses or use a real test server","Confirm you are calling /v1 API routes, not UI routes","Probe /v1/nodes once at startup to catch non-Nomad upstreams early"],"tags":["http","headers","blocking-queries","nomad-api"],"backgroundTag":"missing-response-header","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"}