hashicorp/nomad · error

Invalid variable policy: no variable paths in namespace

Error message

Invalid variable policy: no variable paths in namespace %s

What it means

Returned by acl.Parse in acl/policy.go:594 when a namespace stanza contains a variables block whose Paths list is empty. A variables stanza must define at least one path block to be meaningful, so the parser rejects an empty paths array rather than silently granting nothing.

Solutions

  1. Add at least one path block inside the variables stanza, e.g. path "secret/app" { capabilities = ["read"] }
  2. Remove the entire variables stanza if no variable access is intended
  3. Fix the template/generator so it omits variables when paths are absent

Example fix

// before
namespace "prod" {
  variables {
    paths = []
  }
}
// after
namespace "prod" {
  variables {
    path "secret/app" {
      capabilities = ["read", "list"]
    }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

for _, ns := range policy.Namespaces {
    if ns.Variables != nil && len(ns.Variables.Paths) == 0 {
        return fmt.Errorf("namespace %s: variables stanza needs at least one path", ns.Name)
    }
}

Prevention

When it happens

Trigger: Calling acl.Parse with namespace { variables { paths = [] } } or an HCL variables stanza with no path blocks inside, in any namespace of the policy.

Common situations: Templating tools emitting an empty variables section when no variable grants were configured; hand-removing all path blocks but leaving the variables stanza; JSON policy conversion dropping path entries due to schema mismatch.

Related errors


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

Appendix: source

Thrown at acl/policy.go:594

		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 {
			if len(ns.Variables.Paths) == 0 {
				return nil, fmt.Errorf("Invalid variable policy: no variable paths in namespace %s", ns.Name)
			}
			for _, pathPolicy := range ns.Variables.Paths {
				if pathPolicy.PathSpec == "" {
					return nil, fmt.Errorf("Invalid missing variable path in namespace %s", ns.Name)
				}
				if strings.HasPrefix(pathPolicy.PathSpec, "/") {
					return nil, fmt.Errorf(
						"Invalid variable path %q in namespace %s: cannot start with a leading '/'`",
						pathPolicy.PathSpec, ns.Name)
				}
				for _, cap := range pathPolicy.Capabilities {
					if !isPathCapabilityValid(cap) {
						return nil, fmt.Errorf(
							"Invalid variable capability '%s' in namespace %s", cap, ns.Name)
					}
				}
				pathPolicy.Capabilities = expandVariablesCapabilities(pathPolicy.Capabilities)

View on GitHub (pinned to 482b49bf1a)