{"record":{"id":"4097f3e3d5cbe01b","repo":"hashicorp/nomad","slug":"invalid-key-s-4097f3","errorCode":null,"errorMessage":"invalid key: %s","messagePattern":"invalid key: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/funcs.go","lineNumber":261,"sourceCode":"\tswitch n := node.(type) {\n\tcase *ast.ObjectList:\n\t\tlist = n\n\tcase *ast.ObjectType:\n\t\tlist = n.List\n\tdefault:\n\t\treturn fmt.Errorf(\"cannot check HCL keys of type %T\", n)\n\t}\n\n\tvalidMap := make(map[string]struct{}, len(valid))\n\tfor _, v := range valid {\n\t\tvalidMap[v] = struct{}{}\n\t}\n\n\tvar result error\n\tfor _, item := range list.Items {\n\t\tkey := item.Keys[0].Token.Value().(string)\n\t\tif _, ok := validMap[key]; !ok {\n\t\t\tresult = multierror.Append(result, fmt.Errorf(\n\t\t\t\t\"invalid key: %s\", key))\n\t\t}\n\t}\n\n\treturn result\n}\n\n// UnusedKeys returns a pretty-printed error if any `hcl:\",unusedKeys\"` is not empty\nfunc UnusedKeys(obj interface{}) error {\n\tval := reflect.ValueOf(obj)\n\tif val.Kind() == reflect.Pointer {\n\t\tval = reflect.Indirect(val)\n\t}\n\treturn unusedKeysImpl([]string{}, val)\n}\n\nfunc unusedKeysImpl(path []string, val reflect.Value) error {\n\tstype := val.Type()","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/funcs.go#L243-L279","documentation":"CheckHCLKeys validates that the top-level HCL block/label keys in a parsed body are among an allowlist. When a key (the first token of an HCL item) is not in validMap, it is collected into a multierror with this message. It is the config-schema guard used by quota, storage, device and node-pool parsers to reject unknown attributes early.","triggerScenarios":"Calling parseQuotaSpecImpl, parseQuotaLimits, parseQuotaResource, parseStorageResource, parseDeviceResource or parseNodePoolLimit on HCL content containing an attribute or block whose name is not in the function's valid key list.","commonSituations":"Typos in config keys (e.g. 'quata' instead of 'quota'), keys copied from an older/newer Nomad version whose schema changed, or keys that belong in a nested block but were placed at the top level.","solutions":["Fix the typo or remove the invalid key from the HCL config; the message names the offending key exactly.","Check the docs for the specific block (quota/storage/device/node pool) to confirm supported key names for your version.","If you maintain the parser, add the legitimately new key to the validMap passed to CheckHCLKeys."],"exampleFix":"// before\nquota {\n  limit = 100\n  notes = \"team quota\"\n}\n// after\nquota {\n  limit = 100\n  description = \"team quota\"\n}","handlingStrategy":"validation","validationCode":"// allow only known keys before parsing\nvalidKeys := map[string]struct{}{\"limit\": {}, \"owner\": {}}\nfor _, item := range body.Attributes /* or blocks */ {\n    if _, ok := validKeys[item.Name]; !ok {\n        return fmt.Errorf(\"unsupported key %q; allowed: %v\", item.Name, keysOf(validKeys))\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy key names from the official docs for your Nomad version","Run config through 'nomad validate' before applying","Keep a schema reference/linter for quota and storage stanzas in CI"],"tags":["hcl","config-validation","go"],"backgroundTag":"invalid-config-key","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"}