hashicorp/nomad · error
Failed to parse X-Nomad-Index: %v
Error message
Failed to parse X-Nomad-Index: %v
What it means
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).
Source
Thrown at api/api.go:1187
wm := &WriteMeta{RequestTime: rtt}
parseWriteMeta(resp, wm)
if out != nil {
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
}
return wm, nil
}
// parseQueryMeta is used to help parse query meta-data
func parseQueryMeta(resp *http.Response, q *QueryMeta) error {
header := resp.Header
// Parse the X-Nomad-Index
index, err := strconv.ParseUint(header.Get("X-Nomad-Index"), 10, 64)
if err != nil {
return fmt.Errorf("Failed to parse X-Nomad-Index: %v", err)
}
q.LastIndex = index
// Parse the X-Nomad-LastContact
last, err := strconv.ParseUint(header.Get("X-Nomad-LastContact"), 10, 64)
if err != nil {
return fmt.Errorf("Failed to parse X-Nomad-LastContact: %v", err)
}
if last > math.MaxInt64 {
return fmt.Errorf("Last contact duration is out of range: %d", last)
}
q.LastContact = time.Duration(last) * time.Millisecond
q.NextToken = header.Get("X-Nomad-NextToken")
// Parse the X-Nomad-KnownLeader
switch header.Get("X-Nomad-KnownLeader") {
case "true":
q.KnownLeader = trueView on GitHub (pinned to 482b49bf1a)
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
Example fix
// before: mock handler returns JSON without headers
w.Write([]byte(`{"Nodes":[]}`))
// after
w.Header().Set("X-Nomad-Index", "100")
w.Header().Set("X-Nomad-KnownLeader", "true")
w.Write([]byte(`{"Nodes":[]}`)) Defensive patterns
Strategy: validation
Validate before calling
resp, err := http.Get(cfg.Address + "/v1/nodes")
if err != nil { return err }
if resp.Header.Get("X-Nomad-Index") == "" {
return errors.New("upstream is not a Nomad server (missing X-Nomad-Index)")
} Type guard
func hasNomadMeta(h http.Header) bool {
_, err := strconv.ParseUint(h.Get("X-Nomad-Index"), 10, 64)
return err == nil
} Try / catch
_, qm, err := client.Nodes().List(nil)
if err != nil && strings.Contains(err.Error(), "X-Nomad-Index") {
return fmt.Errorf("responses lack Nomad metadata; check proxy header stripping / non-Nomad upstream: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to unmarshal response with status %d: %v
- unexpected HTTP transport: %T
- invalid redirect location %q: %w
- invalid digest format
- unsupported checksum format
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/96e4c9a016d68ea2.
Report an issue: GitHub.