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

  1. Read the wrapped parser error for the exact line and fix the HCL syntax.
  2. Validate the rules with `nomad acl policy apply` against a test name or use a local HCL linter before applying.
  3. Ensure only supported stanzas (namespace, node, agent, plugin, quota, key, etc.) and capabilities are used; remove unknown keys since strict mode rejects them.
  4. 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

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

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/9b1f90e5470d2843. Report an issue: GitHub.