hashicorp/nomad · error
failed to parse rules: %v
Error message
failed to parse rules: %v
What it means
ACLPolicy.Validate attempts to parse the policy's HCL rules with hashicorp's acl.Parse in strict mode (acl.PolicyParseStrict) and wraps any parse failure as 'failed to parse rules: %v'. This ensures only syntactically valid, fully-known policy documents are stored. The underlying parser error details the offending line/statement.
Source
Thrown at nomad/structs/acl.go:375
func (a *ACLPolicy) Stub() *ACLPolicyListStub {
return &ACLPolicyListStub{
Name: a.Name,
Description: a.Description,
JobACL: a.JobACL,
Hash: a.Hash,
CreateIndex: a.CreateIndex,
ModifyIndex: a.ModifyIndex,
}
}
func (a *ACLPolicy) Validate() error {
var mErr multierror.Error
if !ValidPolicyName.MatchString(a.Name) {
err := fmt.Errorf("invalid name '%s'", a.Name)
mErr.Errors = append(mErr.Errors, err)
}
if _, err := acl.Parse(a.Rules, acl.PolicyParseStrict); err != nil {
err = fmt.Errorf("failed to parse rules: %v", err)
mErr.Errors = append(mErr.Errors, err)
}
if len(a.Description) > maxPolicyDescriptionLength {
err := fmt.Errorf("description longer than %d", maxPolicyDescriptionLength)
mErr.Errors = append(mErr.Errors, err)
}
if a.JobACL != nil {
if a.JobACL.JobID != "" && a.JobACL.Namespace == "" {
err := fmt.Errorf("namespace must be set to set job ID")
mErr.Errors = append(mErr.Errors, err)
}
if a.JobACL.Group != "" && a.JobACL.JobID == "" {
err := fmt.Errorf("job ID must be set to set group")
mErr.Errors = append(mErr.Errors, err)
}
if a.JobACL.Task != "" && a.JobACL.Group == "" {
err := fmt.Errorf("group must be set to set task")
mErr.Errors = append(mErr.Errors, err)View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped parser error for the exact line and fix the HCL syntax.
- Validate the rules with `nomad acl policy apply` against a test name or use a local HCL linter before applying.
- Ensure only supported stanzas (namespace, node, agent, plugin, quota, key, etc.) and capabilities are used; remove unknown keys since strict mode rejects them.
- Compare against a known-good policy from `nomad acl policy info` and correct differences.
Example fix
// before (Rules)
namespace "*" { capabilites = ["list-jobs"] }
// after
namespace "*" { capabilities = ["list-jobs"] } Defensive patterns
Strategy: validation
Validate before calling
func validateRules(rules string) error {
_, err := acl.Parse(rules, acl.PolicyParseStrict)
return err // call before submitting the policy
} Try / catch
if err := policy.Validate(); err != nil {
if strings.Contains(err.Error(), "failed to parse rules") {
return fmt.Errorf("fix policy HCL: %w", err)
}
return err
} Prevention
- Lint policy HCL in CI with acl.Parse strict mode before applying.
- Only use documented Nomad policy stanzas and capabilities (strict mode rejects unknown keys).
- Never paste Consul ACL rules verbatim into Nomad policies.
- Template-generated policies: assert the rendered HCL is non-empty and balanced before submit.
When it happens
Trigger: Creating or updating an ACL policy (via `nomad acl policy apply` or the ACL API) whose Rules HCL is malformed, contains unknown/misspelled stanzas (strict mode rejects unknown keys), or mixes incompatible syntax.
Common situations: Hand-written HCL with typos like 'namespace "*" { capabilities = ["list-jobs"' missing a bracket or quote; copying Consul ACL rules into Nomad policies; stale rules using capabilities renamed across Nomad versions; templating mistakes injecting empty or truncated HCL.
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
- failed to parse %q: %v
- errMissingACLRoleID
- errMissingACLAuthMethodName
- errMissingACLBindingRuleID
- cannot specify ACL role ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/9b1f90e5470d2843.
Report an issue: GitHub.