hashicorp/nomad · error

Invalid namespace policy: %#v

Error message

Invalid namespace policy: %#v

What it means

Returned by acl.Parse in acl/policy.go:574 when a namespace stanza's policy shorthand is non-empty but not one of the accepted values deny, read, write, or scale (isPolicyValid switch). Nomad namespaces accept either the short-hand policy string or fine-grained capabilities, never an arbitrary policy word. The message prints the whole NamespacePolicy struct via %#v.

Source

Thrown at acl/policy.go:574

	// 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) {
				return nil, fmt.Errorf("Invalid namespace capability '%s': %#v", cap, ns)
			}
		}

		// Expand the short hand policy to the capabilities and
		// add to any existing capabilities
		if ns.Policy != "" {
			extraCap := expandNamespacePolicy(ns.Policy)
			ns.Capabilities = append(ns.Capabilities, extraCap...)
		}

		// Expand implicit capabilities
		expandNamespaceCapabilities(ns)

		if ns.Variables != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Change the namespace policy to one of: deny, read, write, scale (exact lowercase)
  2. If the intended grant is fine-grained, drop 'policy' and list explicit 'capabilities' instead
  3. Check the Nomad version: 'scale' is only valid in newer releases; remove it for older agents
  4. Pre-validate with isPolicyValid-equivalent logic or acl.Parse in a unit test

Example fix

// before
namespace "prod" {
  policy = "read-write"
}
// after
namespace "prod" {
  policy = "write"
}
Defensive patterns

Strategy: validation

Validate before calling

var validNsPolicies = map[string]bool{"deny": true, "read": true, "write": true, "scale": true}
for _, ns := range policy.Namespaces {
    if ns.Policy != "" && !validNsPolicies[ns.Policy] {
        return fmt.Errorf("namespace %s: policy %q not in deny|read|write|scale", ns.Name, ns.Policy)
    }
}

Prevention

When it happens

Trigger: Calling acl.Parse with a policy where namespace { policy = "..." } is set to a value outside {deny, read, write, scale} — e.g. "list", "rw", "read-write", "admin", or a case-mismatched variant like "READ".

Common situations: Copy-pasting Consul-style or Vault-style policy words (read/list/root) into Nomad namespace stanzas; typos such as 'writ'; assuming uppercase or 'scale-old' values from older Nomad versions where scale did not exist; generators emitting lowercase-normalized tokens incorrectly.

Related errors


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