{"record":{"id":"f2da81007442d720","repo":"hashicorp/nomad","slug":"failed-to-parse-q-v","errorCode":null,"errorMessage":"failed to parse %q: %v","messagePattern":"failed to parse %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/funcs.go","lineNumber":438,"sourceCode":"func CompileACLObject(cache *ACLCache[*acl.ACL], policies []*ACLPolicy) (*acl.ACL, error) {\n\t// Sort the policies to ensure consistent ordering\n\tsort.Slice(policies, func(i, j int) bool {\n\t\treturn policies[i].Name < policies[j].Name\n\t})\n\n\t// Determine the cache key\n\tcacheKey := ACLPolicyListHash(policies)\n\tentry, ok := cache.Get(cacheKey)\n\tif ok {\n\t\treturn entry.Get(), nil\n\t}\n\n\t// Parse the policies\n\tparsed := make([]*acl.Policy, 0, len(policies))\n\tfor _, policy := range policies {\n\t\tp, err := acl.Parse(policy.Rules, acl.PolicyParseLenient)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse %q: %v\", policy.Name, err)\n\t\t}\n\t\tparsed = append(parsed, p)\n\t}\n\n\t// Create the ACL object\n\taclObj, err := acl.NewACL(false, parsed)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to construct ACL: %v\", err)\n\t}\n\n\t// Update the cache\n\tcache.Add(cacheKey, aclObj)\n\treturn aclObj, nil\n}\n\n// GenerateMigrateToken will create a token for a client to access an\n// authenticated volume of another client to migrate data for sticky volumes.\nfunc GenerateMigrateToken(allocID, nodeSecretID string) (string, error) {","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/funcs.go#L420-L456","documentation":"CompileACLObject parses each ACL policy's HCL rules with hashicorp's acl.Parse (lenient mode) and wraps any parse failure as 'failed to parse \"<policy name>\": <detail>'. It means one of the policies attached to a token is not valid ACL rules, so the token's effective ACL object cannot be compiled.","triggerScenarios":"resolveTokenAndACL / resolveClaims / resolveACLFromToken call CompileACLObject and acl.Parse(policy.Rules) returns an error for the named policy — e.g. malformed HCL, bad stanza names, or corrupted policy stored in state.","commonSituations":"Submitting an ACL policy with HCL syntax mistakes ('nomad acl policy apply' with a broken file); upgrading Nomad and an old policy uses a rule no longer parseable; claims-derived policies with malformed rules.","solutions":["Fix the HCL in the named policy: validate the rules file with 'nomad acl policy apply' on a test cluster or hclfmt-style review","Ensure the policy uses only supported stanzas (namespace/node/agent/service/key/quotas/etc.) with correct rule syntax like 'policy = \"read\"'","Delete and re-create the broken policy via 'nomad acl policy delete <name>' then re-apply a corrected file","If the policy came from workload identity claims, fix the claims-to-policy mapping/template"],"exampleFix":"// before (my-policy.hcl)\nnamespace \"*\" { polic = \"read\" }\n// after\nnamespace \"*\" { policy = \"read\" }","handlingStrategy":"validation","validationCode":"// go: parse policy rules locally before applying\nif _, err := acl.Parse(policyRules, acl.PolicyParseLenient); err != nil {\n    return fmt.Errorf(\"invalid policy HCL for %q: %v\", name, err)\n}","typeGuard":null,"tryCatchPattern":"aclObj, err := structs.CompileACLObject(cache, policies)\nif err != nil {\n    // err names the offending policy inside the message; surface it to the operator\n    return fmt.Errorf(\"token unusable: %w\", err)\n}","preventionTips":["Lint ACL policy HCL before 'nomad acl policy apply'","Use only supported rule stanzas and 'policy = read|write|deny|scale|list' values","Test new policies on a dev cluster or test token first"],"tags":["nomad","acl","hcl","parse-error"],"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"}