hashicorp/nomad · error

Failed to parse ACL Policy: %v

Error message

Failed to parse ACL Policy: %v

What it means

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.).

Source

Thrown at acl/policy.go:559

//
// The "strict" parameter should be set to true if the policy is being created
// or updated, and false if it is being used for evaluation. This allowed us to
// tighten restrictions around unknown keys when writing policies, while not
// breaking existing policies that may have unknown keys when evaluating them,
// since they may have been written before the restrictions were added. The
// constants PolicyParseStrict and PolicyParseLenient can be used to make the
// intent clear at the call site.
func Parse(rules string, strict bool) (*Policy, error) {
	// Decode the rules
	p := &Policy{Raw: rules}
	if rules == "" {
		// Hot path for empty rules
		return p, nil
	}

	// Attempt to parse
	if err := hclDecode(p, rules); err != nil {
		return nil, fmt.Errorf("Failed to parse ACL Policy: %v", err)
	}

	// At least one valid policy must be specified, we don't want to store only
	// raw data
	if p.IsEmpty() {
		return nil, fmt.Errorf("Invalid policy: %s", p.Raw)
	}

	// Validate the policy
	for _, ns := range p.Namespaces {
		if !validNamespace.MatchString(ns.Name) {
			return nil, fmt.Errorf("Invalid namespace name: %#v", ns)
		}
		if ns.Policy != "" && !isPolicyValid(ns.Policy) {
			return nil, fmt.Errorf("Invalid namespace policy: %#v", ns)
		}
		for _, cap := range ns.Capabilities {
			if !isNamespaceCapabilityValid(cap) {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped underlying error after the prefix and fix the reported HCL line/token
  2. Run the policy through a HCL linter or nomad agent config test before applying
  3. Verify only supported stanzas are used for your Nomad version (check docs for namespaces/volumes/variables support)

Example fix

// before
namespace "default" {
  capabilities = ["read", "write"   # missing bracket
}
// after
namespace "default" {
  capabilities = ["read", "write"]
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-check policy HCL locally
_, diags := hclparse.ParseHCL(rules, "policy.hcl")
for _, d := range diags.Errs() { fmt.Println("HCL error:", d) }

Try / catch

p, err := acl.ParsePolicy(rules)
if err != nil {
    return fmt.Errorf("policy rejected: %w", err) // underlying detail follows 'Failed to parse ACL Policy:'
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


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