{"record":{"id":"4467d1d8ee3e4d56","repo":"hashicorp/nomad","slug":"error-parsing-server-s-last-log-term-value-s","errorCode":null,"errorMessage":"error parsing server's last_log_term value: %s","messagePattern":"error parsing server's last_log_term value: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/status_endpoint.go","lineNumber":142,"sourceCode":"\n// RaftStats is used by Autopilot to query the raft stats of the local server.\nfunc (s *Status) RaftStats(args *structs.GenericRequest, reply *structs.RaftStats) error {\n\t// note: we're intentionally throwing away any auth error here and only\n\t// authenticate so that we can measure rate metrics\n\ts.srv.Authenticate(s.ctx, args)\n\ts.srv.MeasureRPCRate(\"status\", structs.RateMetricRead, args)\n\n\tstats := s.srv.raft.Stats()\n\n\tvar err error\n\treply.LastContact = stats[\"last_contact\"]\n\treply.LastIndex, err = strconv.ParseUint(stats[\"last_log_index\"], 10, 64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing server's last_log_index value: %s\", err)\n\t}\n\treply.LastTerm, err = strconv.ParseUint(stats[\"last_log_term\"], 10, 64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing server's last_log_term value: %s\", err)\n\t}\n\n\treturn nil\n}\n\n// HasNodeConn returns whether the server has a connection to the requested\n// Node.\nfunc (s *Status) HasNodeConn(args *structs.NodeSpecificRequest, reply *structs.NodeConnQueryResponse) error {\n\t// note: we're intentionally throwing away any auth error here and only\n\t// authenticate so that we can measure rate metrics\n\ts.srv.Authenticate(s.ctx, args)\n\ts.srv.MeasureRPCRate(\"status\", structs.RateMetricRead, args)\n\n\t// Validate the args\n\tif args.NodeID == \"\" {\n\t\treturn errors.New(\"Must provide the NodeID\")\n\t}\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/status_endpoint.go#L124-L160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nterm := reply.LastTerm // assume fine\n// after (server-side defensive parse)\nif lastTerm, ok := stats[\"last_log_term\"]; ok && lastTerm != \"\" {\n  reply.LastTerm, err = strconv.ParseUint(lastTerm, 10, 64)\n} else {\n  return fmt.Errorf(\"last_log_term missing from raft stats\")\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"func isRaftTermParseError(err error) bool { return err != nil && strings.Contains(err.Error(), \"last_log_term\") }","tryCatchPattern":"stats, err := srv.Status().RaftStats()\nif isRaftTermParseError(err) {\n  return fmt.Errorf(\"raft term unavailable: %w (use 'nomad operator raft list-peers')\", err)\n}","preventionTips":["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."],"tags":["nomad","raft","parsing","rpc"],"backgroundTag":"raft-stats-parse-error","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"}