hashicorp/nomad · error
error parsing server's last_log_term value: %s
Error message
error parsing server's last_log_term value: %s
What it means
Same endpoint as the last_log_index variant: RaftStats parses stats["last_log_term"] with strconv.ParseUint after successfully parsing the index. Failure means the raft library returned a last_log_term value that is empty or not a valid uint64, violating the expected raft stats contract.
Source
Thrown at nomad/status_endpoint.go:142
// RaftStats is used by Autopilot to query the raft stats of the local server.
func (s *Status) RaftStats(args *structs.GenericRequest, reply *structs.RaftStats) error {
// note: we're intentionally throwing away any auth error here and only
// authenticate so that we can measure rate metrics
s.srv.Authenticate(s.ctx, args)
s.srv.MeasureRPCRate("status", structs.RateMetricRead, args)
stats := s.srv.raft.Stats()
var err error
reply.LastContact = stats["last_contact"]
reply.LastIndex, err = strconv.ParseUint(stats["last_log_index"], 10, 64)
if err != nil {
return fmt.Errorf("error parsing server's last_log_index value: %s", err)
}
reply.LastTerm, err = strconv.ParseUint(stats["last_log_term"], 10, 64)
if err != nil {
return fmt.Errorf("error parsing server's last_log_term value: %s", err)
}
return nil
}
// HasNodeConn returns whether the server has a connection to the requested
// Node.
func (s *Status) HasNodeConn(args *structs.NodeSpecificRequest, reply *structs.NodeConnQueryResponse) error {
// note: we're intentionally throwing away any auth error here and only
// authenticate so that we can measure rate metrics
s.srv.Authenticate(s.ctx, args)
s.srv.MeasureRPCRate("status", structs.RateMetricRead, args)
// Validate the args
if args.NodeID == "" {
return errors.New("Must provide the NodeID")
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the wrapped strconv message to confirm whether the value was empty vs malformed.
- Align Nomad client/server versions; ensure the server binary links the expected hashicorp/raft.
- Retry the call once the server has completed raft setup and elected a leader.
- Fall back to 'nomad operator raft list-peers' for leader/term information if the endpoint keeps failing.
Example fix
// before
term := reply.LastTerm // assume fine
// after (server-side defensive parse)
if lastTerm, ok := stats["last_log_term"]; ok && lastTerm != "" {
reply.LastTerm, err = strconv.ParseUint(lastTerm, 10, 64)
} else {
return fmt.Errorf("last_log_term missing from raft stats")
} Defensive patterns
Strategy: retry
Type guard
func isRaftTermParseError(err error) bool { return err != nil && strings.Contains(err.Error(), "last_log_term") } Try / catch
stats, err := srv.Status().RaftStats()
if isRaftTermParseError(err) {
return fmt.Errorf("raft term unavailable: %w (use 'nomad operator raft list-peers')", err)
} Prevention
- Upgrade clients and servers together when raft internals change.
- Retry after election completes rather than failing fast on transient parse errors.
- Cross-check with 'nomad operator raft list-peers' for term/leader info.
When it happens
Trigger: Status().RaftStats RPC where strconv.ParseUint(stats["last_log_term"], 10, 64) fails — typically an empty string in the stats map from an uninitialized or incompatible raft instance.
Common situations: Nomad version mismatch between client expectations and server raft library; querying during very early server startup before raft has written any term; custom raft builds.
Related errors
- error parsing server's last_log_index value: %s
- no servers
- users: unable to parse uid/gid from username
- <combined HCL diagnostics from str.String()>
- missing NodeID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4467d1d8ee3e4d56.
Report an issue: GitHub.