{"record":{"id":"445e26934d12a2e9","repo":"hashicorp/nomad","slug":"evals-field-must-not-be-set","errorCode":null,"errorMessage":"evals field must not be set","messagePattern":"evals field must not be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/node_endpoint.go","lineNumber":1556,"sourceCode":"\t\treturn fmt.Errorf(\"failed to retrieve node %s: %v\", targetNodeID, err)\n\t}\n\tif node == nil {\n\t\treturn fmt.Errorf(\"node %s not found\", targetNodeID)\n\t}\n\tif !aclObj.AllowClientOp(node.NodePool) {\n\t\treturn structs.ErrPermissionDenied\n\t}\n\tif err := auth.AuthorizeSameNode(args.GetIdentity(), targetNodeID); err != nil {\n\t\treturn err\n\t}\n\tif node.UnresponsiveStatus() {\n\t\treturn fmt.Errorf(\"node %s is not allowed to update allocs while in status %s\", targetNodeID, node.Status)\n\t}\n\n\t// Ensure that evals aren't set from client RPCs\n\t// We create them here before the raft update\n\tif len(args.Evals) != 0 {\n\t\treturn fmt.Errorf(\"evals field must not be set\")\n\t}\n\n\t// Update modified timestamp for client initiated allocation updates\n\tnow := time.Now()\n\tvar evals []*structs.Evaluation\n\n\tfor _, allocToUpdate := range args.Alloc {\n\t\tevalTriggerBy := \"\"\n\t\tallocToUpdate.ModifyTime = now.UTC().UnixNano()\n\n\t\talloc, _ := n.srv.State().AllocByID(nil, allocToUpdate.ID)\n\t\tif alloc == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif !allocToUpdate.TerminalStatus() && alloc.ClientStatus != structs.AllocClientStatusUnknown {\n\t\t\tcontinue\n\t\t}","sourceCodeStart":1538,"sourceCodeEnd":1574,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/node_endpoint.go#L1538-L1574","documentation":"Nomad's UpdateAlloc RPC rejects client-submitted evaluations. Evals are generated server-side inside the endpoint before the Raft update, so a request carrying args.Evals is treated as invalid/malicious input and rejected. This protects the internal scheduler workflow from clients fabricating evaluations.","triggerScenarios":"A Nomad client (node agent) sends a Node.UpdateAlloc RPC with the Evals field populated; only CreateEval, MigrateToken, Preempted fields are accepted from clients.","commonSituations":"Custom or patched Nomad clients (e.g. third-party schedulers, forked drivers, or integration tooling) that copy a full Allocation struct into the update request instead of zeroing Evals; version drift where a newer client sets Evals.","solutions":["Clear the Evals field on the NodeUpdateAllocRequest before sending it (args.Evals = nil)","Only populate the allowed fields (Allocation fields like TaskStates/DesiredStatus) and construct the request with a fresh structs.NodeUpdateAllocRequest","If you need to create an eval as a user, use the Eval endpoints or the Nomad API /v1/evaluations, not UpdateAlloc","Check your client code for copying of a structs.Allocation into args and strip internal-only fields"],"exampleFix":"// before\nargs := structs.NodeUpdateAllocRequest{Eval: myEval, Evals: evals, Alloc: alloc}\n// after\nargs := structs.NodeUpdateAllocRequest{Alloc: alloc} // evals are created by the server","handlingStrategy":"validation","validationCode":"if len(req.Evals) != 0 {\n    return fmt.Errorf(\"client must not set Evals on NodeUpdateAllocRequest\")\n}\n// or proactively: req.Evals = nil before sending","typeGuard":"func evalsUnset(req *structs.NodeUpdateAllocRequest) bool { return len(req.Evals) == 0 }","tryCatchPattern":null,"preventionTips":["Construct NodeUpdateAllocRequest fresh instead of copying internal structs","Never populate server-owned fields (Evals, Eval) in client RPCs","Review custom clients against the current structs.NodeUpdateAllocRequest definition after upgrades","Use the eval API for eval creation rather than UpdateAlloc"],"tags":["nomad","rpc","validation","client-server"],"backgroundTag":"forbidden-request-field","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"}