hashicorp/nomad · error
Invalid variable capability '%s' in namespace %s
Error message
Invalid variable capability '%s' in namespace %s
What it means
Returned by acl.Parse in acl/policy.go:607 when a variables path block lists a capability not accepted by isPathCapabilityValid (acl/policy.go:314). Variables path capabilities are limited to write, read, list, destroy, and deny; any other string (including namespace capabilities like submit-job) is rejected.
Source
Thrown at acl/policy.go:607
// 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)
}
}
// Remove the namespace name from the extra key list.
p.removeExtraKey(ns.Name)
}
for _, np := range p.NodePools {
if !validNodePool.MatchString(np.Name) {
return nil, fmt.Errorf("Invalid node pool name '%s'", np.Name)
}
if np.Policy != "" && !isPolicyValid(np.Policy) {
return nil, fmt.Errorf("Invalid node pool policy '%s' for '%s'", np.Policy, np.Name)View on GitHub (pinned to 482b49bf1a)
Solutions
- Use only read, write, list, destroy, or deny in variables path capabilities (exact lowercase)
- Replace 'delete' with 'destroy' (most common confusion)
- Move non-variable capabilities into the namespace stanza's capabilities list
- Pre-validate each capability against the fixed set of five before calling Parse
Example fix
// before
variables {
path "secret/app" {
capabilities = ["read", "delete"]
}
}
// after
variables {
path "secret/app" {
capabilities = ["read", "destroy"]
}
} Defensive patterns
Strategy: validation
Validate before calling
var validVarCaps = map[string]bool{"read": true, "write": true, "list": true, "destroy": true, "deny": true}
for _, ns := range policy.Namespaces {
if ns.Variables == nil { continue }
for _, p := range ns.Variables.Paths {
for _, c := range p.Capabilities {
if !validVarCaps[c] { return fmt.Errorf("bad variables capability %q", c) }
}
}
} Prevention
- Restrict variables path capabilities to read/write/list/destroy/deny
- Remember 'delete' does not exist for variables — it is 'destroy'
- Lint policies per stanza type with its own capability enum
When it happens
Trigger: Calling acl.Parse with path { capabilities = [...] } in a variables stanza containing values outside {read, write, list, destroy, deny} — misspellings, uppercase forms, or namespace/node-pool capabilities pasted into a variables path.
Common situations: Copy-pasting namespace capabilities into variables stanzas; typos like 'delete' (correct word is 'destroy'); uppercase 'READ'; generators reusing a generic capability enum.
Related errors
- Invalid namespace capability '%s': %#v
- Invalid variable policy: no variable paths in namespace %s
- Invalid missing variable path in namespace %s
- Invalid variable path %q in namespace %s: cannot start with
- Invalid node pool capability '%s' for '%s'
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5239169ec1891a13.
Report an issue: GitHub.