{"record":{"id":"6069fd2860c71587","repo":"hashicorp/nomad","slug":"invalid-node-pool-name-s","errorCode":null,"errorMessage":"Invalid node pool name '%s'","messagePattern":"Invalid node pool name '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"acl/policy.go","lineNumber":622,"sourceCode":"\t\t\t\t}\n\t\t\t\tfor _, cap := range pathPolicy.Capabilities {\n\t\t\t\t\tif !isPathCapabilityValid(cap) {\n\t\t\t\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\t\t\t\"Invalid variable capability '%s' in namespace %s\", cap, ns.Name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpathPolicy.Capabilities = expandVariablesCapabilities(pathPolicy.Capabilities)\n\n\t\t\t}\n\t\t}\n\n\t\t// Remove the namespace name from the extra key list.\n\t\tp.removeExtraKey(ns.Name)\n\t}\n\n\tfor _, np := range p.NodePools {\n\t\tif !validNodePool.MatchString(np.Name) {\n\t\t\treturn nil, fmt.Errorf(\"Invalid node pool name '%s'\", np.Name)\n\t\t}\n\t\tif np.Policy != \"\" && !isPolicyValid(np.Policy) {\n\t\t\treturn nil, fmt.Errorf(\"Invalid node pool policy '%s' for '%s'\", np.Policy, np.Name)\n\t\t}\n\t\tfor _, cap := range np.Capabilities {\n\t\t\tif !isNodePoolCapabilityValid(cap) {\n\t\t\t\treturn nil, fmt.Errorf(\"Invalid node pool capability '%s' for '%s'\", cap, np.Name)\n\t\t\t}\n\t\t}\n\n\t\tif np.Policy != \"\" {\n\t\t\textraCap := expandNodePoolPolicy(np.Policy)\n\t\t\tnp.Capabilities = append(np.Capabilities, extraCap...)\n\t\t}\n\n\t\t// Remove the node-pool name from the extra key list.\n\t\tp.removeExtraKey(np.Name)\n\t}","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/acl/policy.go#L604-L640","documentation":"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.","triggerScenarios":"Calling acl.Parse with node_pool { name = ... } containing illegal characters (spaces, dots, slashes), an empty name, or a name over 128 characters.","commonSituations":"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.","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"],"exampleFix":"// before\nnode_pool \"prod.pool\" {\n  policy = \"write\"\n}\n// after\nnode_pool \"prod-pool\" {\n  policy = \"write\"\n}","handlingStrategy":"validation","validationCode":"var validNodePool = regexp.MustCompile(`^[a-zA-Z0-9-_*]{1,128}$`)\nfor _, np := range policy.NodePools {\n    if !validNodePool.MatchString(np.Name) {\n        return fmt.Errorf(\"node pool %q does not match %s\", np.Name, validNodePool)\n    }\n}","typeGuard":"func hasValidNodePoolName(name string) bool {\n    return len(name) >= 1 && len(name) <= 128 &&\n        strings.IndexFunc(name, func(r rune) bool {\n            return !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_' || r == '*')\n        }) == -1\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["nomad","acl","node-pool","policy-validation"],"backgroundTag":"acl-policy-validation-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}