{"record":{"id":"0857cfd3387446e3","repo":"hashicorp/nomad","slug":"failed-to-parse-acl-policy-v","errorCode":null,"errorMessage":"Failed to parse ACL Policy: %v","messagePattern":"Failed to parse ACL Policy: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"acl/policy.go","lineNumber":559,"sourceCode":"//\n// The \"strict\" parameter should be set to true if the policy is being created\n// or updated, and false if it is being used for evaluation. This allowed us to\n// tighten restrictions around unknown keys when writing policies, while not\n// breaking existing policies that may have unknown keys when evaluating them,\n// since they may have been written before the restrictions were added. The\n// constants PolicyParseStrict and PolicyParseLenient can be used to make the\n// intent clear at the call site.\nfunc Parse(rules string, strict bool) (*Policy, error) {\n\t// Decode the rules\n\tp := &Policy{Raw: rules}\n\tif rules == \"\" {\n\t\t// Hot path for empty rules\n\t\treturn p, nil\n\t}\n\n\t// Attempt to parse\n\tif err := hclDecode(p, rules); err != nil {\n\t\treturn nil, fmt.Errorf(\"Failed to parse ACL Policy: %v\", err)\n\t}\n\n\t// At least one valid policy must be specified, we don't want to store only\n\t// raw data\n\tif p.IsEmpty() {\n\t\treturn nil, fmt.Errorf(\"Invalid policy: %s\", p.Raw)\n\t}\n\n\t// Validate the policy\n\tfor _, ns := range p.Namespaces {\n\t\tif !validNamespace.MatchString(ns.Name) {\n\t\t\treturn nil, fmt.Errorf(\"Invalid namespace name: %#v\", ns)\n\t\t}\n\t\tif ns.Policy != \"\" && !isPolicyValid(ns.Policy) {\n\t\t\treturn nil, fmt.Errorf(\"Invalid namespace policy: %#v\", ns)\n\t\t}\n\t\tfor _, cap := range ns.Capabilities {\n\t\t\tif !isNamespaceCapabilityValid(cap) {","sourceCodeStart":541,"sourceCodeEnd":577,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/acl/policy.go#L541-L577","documentation":"acl/policy.go:559 (Parse) wraps any failure of hclDecode on the policy rules text with 'Failed to parse ACL Policy: %v'. The underlying error names the exact HCL problem — a Nomad ACL policy document must be valid HCL with recognized stanza types (namespace, node, service, key, quota, etc.).","triggerScenarios":"Submitting an ACL policy (nomad acl policy apply, or the API PUT to /v1/acl/policy) whose rules string fails HCL decoding: syntax errors, unknown top-level stanzas, wrong value types in stanzas.","commonSituations":"Copy-pasted policy missing a closing brace; deprecated/renamed stanza from old Consul/Nomad policy examples; YAML mistakenly pasted instead of HCL; quoting errors around policy content in shell heredocs.","solutions":["Read the wrapped underlying error after the prefix and fix the reported HCL line/token","Run the policy through a HCL linter or nomad agent config test before applying","Verify only supported stanzas are used for your Nomad version (check docs for namespaces/volumes/variables support)"],"exampleFix":"// before\nnamespace \"default\" {\n  capabilities = [\"read\", \"write\"   # missing bracket\n}\n// after\nnamespace \"default\" {\n  capabilities = [\"read\", \"write\"]\n}","handlingStrategy":"validation","validationCode":"// pre-check policy HCL locally\n_, diags := hclparse.ParseHCL(rules, \"policy.hcl\")\nfor _, d := range diags.Errs() { fmt.Println(\"HCL error:\", d) }","typeGuard":null,"tryCatchPattern":"p, err := acl.ParsePolicy(rules)\nif err != nil {\n    return fmt.Errorf(\"policy rejected: %w\", err) // underlying detail follows 'Failed to parse ACL Policy:'\n}","preventionTips":["Lint ACL policies with HCL tooling before applying","Use heredocs/quoted files to avoid shell mangling","Keep policies updated to current stanza vocabulary per Nomad version"],"tags":["acl","policy","hcl","parsing"],"backgroundTag":"acl-policy-parse-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"}