hashicorp/nomad · error
failed to parse %q: %v
Error message
failed to parse %q: %v
What it means
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.
Source
Thrown at nomad/structs/funcs.go:438
func CompileACLObject(cache *ACLCache[*acl.ACL], policies []*ACLPolicy) (*acl.ACL, error) {
// Sort the policies to ensure consistent ordering
sort.Slice(policies, func(i, j int) bool {
return policies[i].Name < policies[j].Name
})
// Determine the cache key
cacheKey := ACLPolicyListHash(policies)
entry, ok := cache.Get(cacheKey)
if ok {
return entry.Get(), nil
}
// Parse the policies
parsed := make([]*acl.Policy, 0, len(policies))
for _, policy := range policies {
p, err := acl.Parse(policy.Rules, acl.PolicyParseLenient)
if err != nil {
return nil, fmt.Errorf("failed to parse %q: %v", policy.Name, err)
}
parsed = append(parsed, p)
}
// Create the ACL object
aclObj, err := acl.NewACL(false, parsed)
if err != nil {
return nil, fmt.Errorf("failed to construct ACL: %v", err)
}
// Update the cache
cache.Add(cacheKey, aclObj)
return aclObj, nil
}
// GenerateMigrateToken will create a token for a client to access an
// authenticated volume of another client to migrate data for sticky volumes.
func GenerateMigrateToken(allocID, nodeSecretID string) (string, error) {View on GitHub (pinned to 482b49bf1a)
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
Example fix
// before (my-policy.hcl)
namespace "*" { polic = "read" }
// after
namespace "*" { policy = "read" } Defensive patterns
Strategy: validation
Validate before calling
// go: parse policy rules locally before applying
if _, err := acl.Parse(policyRules, acl.PolicyParseLenient); err != nil {
return fmt.Errorf("invalid policy HCL for %q: %v", name, err)
} Try / catch
aclObj, err := structs.CompileACLObject(cache, policies)
if err != nil {
// err names the offending policy inside the message; surface it to the operator
return fmt.Errorf("token unusable: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid or duplicate policy keys: %v
- failed to parse rules: %v
- failed to parse config:
- failed to convert task schema
- <combined HCL diagnostics from str.String()>
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/f2da81007442d720.
Report an issue: GitHub.