{"record":{"id":"61b61c4133436ff8","repo":"hashicorp/nomad","slug":"invalid-node-policy-v","errorCode":null,"errorMessage":"Invalid node policy: %#v","messagePattern":"Invalid node policy: %#v","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"acl/policy.go","lineNumber":683,"sourceCode":"\n\t// Now that we have processed all known keys, return an error if the\n\t// operator wrote a policy with unknown keys if we are being strict. While\n\t// these do not grant any extra privileges, it can be misleaing to allow\n\t// these and cause problems later if we add new capabilities that collide\n\t// with the unknown keys.\n\tif len(p.ExtraKeysHCL) > 0 && strict {\n\t\treturn nil, fmt.Errorf(\"Invalid or duplicate policy keys: %v\",\n\t\t\tstrings.Join(p.ExtraKeysHCL, \", \"))\n\t}\n\n\tp.ExtraKeysHCL = nil\n\n\tif p.Agent != nil && !isPolicyValid(p.Agent.Policy) {\n\t\treturn nil, fmt.Errorf(\"Invalid agent policy: %#v\", p.Agent)\n\t}\n\n\tif p.Node != nil && !isPolicyValid(p.Node.Policy) {\n\t\treturn nil, fmt.Errorf(\"Invalid node policy: %#v\", p.Node)\n\t}\n\n\tif p.Operator != nil {\n\t\tif p.Operator.Policy != \"\" && !isPolicyValid(p.Operator.Policy) {\n\t\t\treturn nil, fmt.Errorf(\"Invalid operator policy: %#v\", p.Operator)\n\t\t}\n\t\tfor _, cap := range p.Operator.Capabilities {\n\t\t\tif !isOperatorCapabilityValid(cap) {\n\t\t\t\treturn nil, fmt.Errorf(\"Invalid operator capability '%s'\", cap)\n\t\t\t}\n\t\t}\n\n\t\t// Expand the short hand policy to the capabilities and\n\t\t// add to any existing capabilities\n\t\tif p.Operator.Policy != \"\" {\n\t\t\textraCap := expandOperatorPolicy(p.Operator.Policy)\n\t\t\tp.Operator.Capabilities = append(p.Operator.Capabilities, extraCap...)\n\t\t}","sourceCodeStart":665,"sourceCodeEnd":701,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/acl/policy.go#L665-L701","documentation":"acl.Parse (acl/policy.go:683) validates the top-level node block's Policy string with isPolicyValid, which only accepts deny, read, write, scale. Any other value fails parsing and rejects the whole policy. The offending NodePolicy struct is printed via %#v.","triggerScenarios":"acl.Parse on a policy containing node { policy = \"<invalid>\" } where the value is not exactly \"deny\", \"read\", \"write\", or \"scale\" — e.g. 'list', 'sudo', or a case-mismatched 'Read'.","commonSituations":"Legacy Nomad policies or hand-written policies using pre-0.8 style values; copying the client 'enabled' concept into policy; tooling that fills the policy from a dropdown with wrong values.","solutions":["Set the node block's policy to exactly one of: deny, read, write, scale (lowercase).","If fine-grained node permissions are needed, ensure you are on a Nomad version supporting node capabilities and use those instead.","Check the %#v struct printed in the error to confirm the offending value."],"exampleFix":"// before\nnode {\n  policy = \"sudo\"\n}\n// after\nnode {\n  policy = \"write\"\n}","handlingStrategy":"validation","validationCode":"if policy.Node != nil && policy.Node.Policy != \"\" &&\n    !map[string]bool{\"deny\": true, \"read\": true, \"write\": true, \"scale\": true}[policy.Node.Policy] {\n    return fmt.Errorf(\"node policy %q must be deny|read|write|scale\", policy.Node.Policy)\n}","typeGuard":"func isPolicyValid(policy string) bool {\n    switch policy {\n    case \"deny\", \"read\", \"write\", \"scale\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"_, err := acl.Parse(rules, acl.PolicyParseStrict)\nif err != nil {\n    if strings.Contains(err.Error(), \"Invalid node policy\") {\n        // correct the node block's policy to a valid shorthand\n    }\n    return err\n}","preventionTips":["Use only deny, read, write, scale in the node block's policy field","Watch for case sensitivity — 'Read' is invalid","Migrate pre-0.8 style node policy values to current shorthand values"],"tags":["nomad","acl","policy-validation","node"],"backgroundTag":"acl-policy-validation-failed","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"}