hashicorp/nomad · error
Invalid host volume policy: %#v
Error message
Invalid host volume policy: %#v
What it means
acl.Parse() (acl/policy.go:647) checks each host_volume block's shorthand Policy field against the allowed values deny, read, write, scale via isPolicyValid. A non-empty policy string with any other value (typo, wrong case, or an invalid value like 'list') aborts parsing. Note that the Policy field is optional — it is only validated when non-empty.
Source
Thrown at acl/policy.go:647
return nil, fmt.Errorf("Invalid node pool capability '%s' for '%s'", cap, np.Name)
}
}
if np.Policy != "" {
extraCap := expandNodePoolPolicy(np.Policy)
np.Capabilities = append(np.Capabilities, extraCap...)
}
// Remove the node-pool name from the extra key list.
p.removeExtraKey(np.Name)
}
for _, hv := range p.HostVolumes {
if !validVolume.MatchString(hv.Name) {
return nil, fmt.Errorf("Invalid host volume name: %#v", hv)
}
if hv.Policy != "" && !isPolicyValid(hv.Policy) {
return nil, fmt.Errorf("Invalid host volume policy: %#v", hv)
}
for _, cap := range hv.Capabilities {
if !isHostVolumeCapabilityValid(cap) {
return nil, fmt.Errorf("Invalid host volume capability '%s': %#v", cap, hv)
}
}
// Expand the short hand policy to the capabilities and
// add to any existing capabilities
if hv.Policy != "" {
extraCap := expandHostVolumePolicy(hv.Policy)
hv.Capabilities = append(hv.Capabilities, extraCap...)
}
// Remove the host-volume name from the extra key list.
p.removeExtraKey(hv.Name)
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Set policy to one of exactly: deny, read, write, or scale (lowercase).
- If you need mount granularity, remove the policy field and use capabilities = ["mount-readonly"] or ["mount-readwrite"] instead.
- Check the printed %#v struct to confirm which host_volume block carries the bad Policy value.
Example fix
// before
host_volume "data" {
policy = "readonly"
}
// after
host_volume "data" {
capabilities = ["mount-readonly"]
} Defensive patterns
Strategy: validation
Validate before calling
var validPolicies = map[string]bool{"deny": true, "read": true, "write": true, "scale": true}
for _, hv := range policy.HostVolumes {
if hv.Policy != "" && !validPolicies[hv.Policy] {
return fmt.Errorf("host_volume %q: policy %q must be deny|read|write|scale", hv.Name, hv.Policy)
}
} Type guard
func isPolicyValid(policy string) bool {
switch policy {
case "deny", "read", "write", "scale":
return true
}
return false
} Try / catch
_, err := acl.Parse(rules, acl.PolicyParseStrict)
if err != nil {
if strings.Contains(err.Error(), "Invalid host volume policy") {
// log the bad shorthand policy and correct to deny|read|write|scale
}
return err
} Prevention
- Only use the lowercase literals deny, read, write, scale in the policy field
- Use capabilities = ["mount-readonly"|"mount-readwrite"] for fine-grained access instead of inventing policy values
- Keep a shared constants list of valid policy strings in tooling that generates policies
When it happens
Trigger: acl.Parse on a policy containing host_volume "name" { policy = "<invalid>" } where the string is not exactly "deny", "read", "write", or "scale".
Common situations: Typos such as 'Read' (capitalized) or 'readonly'; reusing capability names like 'mount-readonly' in the shorthand policy field instead of the capabilities list; copying a CSI/plugin policy value into a host_volume block.
Related errors
- Invalid host volume name: %#v
- Invalid namespace name: %#v
- Invalid namespace policy: %#v
- Invalid namespace capability '%s': %#v
- Invalid variable policy: no variable paths in namespace %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1aa30e7bdf80fb2d.
Report an issue: GitHub.