hashicorp/nomad · error
Invalid node pool name '%s'
Error message
Invalid node pool name '%s'
What it means
Returned by acl.Parse in acl/policy.go:622 when a node_pool stanza's Name fails the validNodePool regex ^[a-zA-Z0-9-_*]{1,128}$ — allowed characters are letters, digits, hyphen, underscore, and asterisk, max 128 chars. Unlike namespaces, underscores ARE permitted for node pools, so the same name may be valid for one stanza type and invalid for the other.
Source
Thrown at acl/policy.go:622
}
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)
}
for _, cap := range np.Capabilities {
if !isNodePoolCapabilityValid(cap) {
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)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Rename the node pool to match ^[a-zA-Z0-9-_*]{1,128}$ (letters, digits, hyphen, underscore, asterisk)
- Remove leading/trailing whitespace and empty interpolations
- Shorten the name to <= 128 characters
- Pre-validate with the same regex in config CI before applying the policy
Example fix
// before
node_pool "prod.pool" {
policy = "write"
}
// after
node_pool "prod-pool" {
policy = "write"
} Defensive patterns
Strategy: validation
Validate before calling
var validNodePool = regexp.MustCompile(`^[a-zA-Z0-9-_*]{1,128}$`)
for _, np := range policy.NodePools {
if !validNodePool.MatchString(np.Name) {
return fmt.Errorf("node pool %q does not match %s", np.Name, validNodePool)
}
} Type guard
func hasValidNodePoolName(name string) bool {
return len(name) >= 1 && len(name) <= 128 &&
strings.IndexFunc(name, func(r rune) bool {
return !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_' || r == '*')
}) == -1
} Prevention
- Validate node pool names against ^[a-zA-Z0-9-_*]{1,128}$ before applying policies
- Note underscores are allowed here but NOT in namespace names — do not share name validators
- Sanitize generated names (URL decoding, team labels) before embedding in policies
When it happens
Trigger: Calling acl.Parse with node_pool { name = ... } containing illegal characters (spaces, dots, slashes), an empty name, or a name over 128 characters.
Common situations: Typos like "pool.1" or "team pool"; empty names from template interpolation; using the stricter namespace rules mentally and renaming pool names that contain dots; generated names with URL-encoded characters.
Related errors
- Invalid node pool policy '%s' for '%s'
- 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/6069fd2860c71587.
Report an issue: GitHub.