hashicorp/nomad · error
Failed to parse X-Nomad-LastContact: %v
Error message
Failed to parse X-Nomad-LastContact: %v
What it means
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.
Source
Thrown at api/api.go:1194
}
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 = true
default:
q.KnownLeader = false
}
return nil
}
// parseWriteMeta is used to help parse write meta-dataView on GitHub (pinned to 482b49bf1a)
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
Example fix
// before
c.Error = httpResp.Header.Get("X-Nomad-LastContact") // empty through proxy
// after
proxy_pass_headers X-Nomad-LastContact; // nginx: forward X-Nomad-* headers Defensive patterns
Strategy: validation
Validate before calling
resp, _ := http.Get(url)
if v := resp.Header.Get("X-Nomad-LastContact"); v == "" {
if _, err := strconv.ParseUint(v, 10, 64); err != nil {
return fmt.Errorf("server did not return a valid X-Nomad-LastContact header")
}
} Type guard
func hasValidLastContact(h http.Header) bool {
_, err := strconv.ParseUint(h.Get("X-Nomad-LastContact"), 10, 64)
return err == nil
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- Last contact duration is out of range: %d
- users: unable to parse uid/gid from username
- <combined HCL diagnostics from str.String()>
- Failed to parse ACL Policy: %v
- unable to unmarshal response with status %d: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6a3a457f6d62d649.
Report an issue: GitHub.