hashicorp/nomad · error

invalid key: %s

Error message

invalid key: %s

What it means

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.

Source

Thrown at helper/funcs.go:261

	switch n := node.(type) {
	case *ast.ObjectList:
		list = n
	case *ast.ObjectType:
		list = n.List
	default:
		return fmt.Errorf("cannot check HCL keys of type %T", n)
	}

	validMap := make(map[string]struct{}, len(valid))
	for _, v := range valid {
		validMap[v] = struct{}{}
	}

	var result error
	for _, item := range list.Items {
		key := item.Keys[0].Token.Value().(string)
		if _, ok := validMap[key]; !ok {
			result = multierror.Append(result, fmt.Errorf(
				"invalid key: %s", key))
		}
	}

	return result
}

// UnusedKeys returns a pretty-printed error if any `hcl:",unusedKeys"` is not empty
func UnusedKeys(obj interface{}) error {
	val := reflect.ValueOf(obj)
	if val.Kind() == reflect.Pointer {
		val = reflect.Indirect(val)
	}
	return unusedKeysImpl([]string{}, val)
}

func unusedKeysImpl(path []string, val reflect.Value) error {
	stype := val.Type()

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Fix the typo or remove the invalid key from the HCL config; the message names the offending key exactly.
  2. Check the docs for the specific block (quota/storage/device/node pool) to confirm supported key names for your version.
  3. If you maintain the parser, add the legitimately new key to the validMap passed to CheckHCLKeys.

Example fix

// before
quota {
  limit = 100
  notes = "team quota"
}
// after
quota {
  limit = 100
  description = "team quota"
}
Defensive patterns

Strategy: validation

Validate before calling

// allow only known keys before parsing
validKeys := map[string]struct{}{"limit": {}, "owner": {}}
for _, item := range body.Attributes /* or blocks */ {
    if _, ok := validKeys[item.Name]; !ok {
        return fmt.Errorf("unsupported key %q; allowed: %v", item.Name, keysOf(validKeys))
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/4097f3e3d5cbe01b. Report an issue: GitHub.