hashicorp/nomad · error

%sunexpected keys %s

Error message

%sunexpected keys %s

What it means

unusedKeysImpl walks a struct via reflection (UnusedKeys helper) and reports any leftover keys recorded in []string fields (typically 'unused keys' slices populated by mapstructure WeakDecode). It prefixes the error with the dotted struct path so the caller knows where the unexpected keys were found.

Source

Thrown at helper/funcs.go:316

		}

		// Search the hcl tags for "unusedKeys"
		unusedKeys := false
		for _, p := range tags {
			if p == "unusedKeys" {
				unusedKeys = true
				break
			}
		}

		if unusedKeys {
			ks, ok := fval.Interface().([]string)
			if ok && len(ks) != 0 {
				ps := ""
				if len(path) > 0 {
					ps = strings.Join(path, ".") + " "
				}
				return fmt.Errorf("%sunexpected keys %s",
					ps,
					strings.Join(ks, ", "))
			}
		}
	}
	return nil
}

// RemoveEqualFold removes the first string that EqualFold matches. It updates xs in place
func RemoveEqualFold(xs *[]string, search string) {
	sl := *xs
	for i, x := range sl {
		if strings.EqualFold(x, search) {
			sl = append(sl[:i], sl[i+1:]...)
			if len(sl) == 0 {
				*xs = nil
			} else {
				*xs = sl

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove the listed keys from the input config (they are printed after 'unexpected keys').
  2. Add matching fields to the target struct if the keys are valid but unsupported by the decoder.
  3. If the keys are intentionally ignorable, skip the UnusedKeys check for that struct or clear the unused-keys field.

Example fix

// before
resources {
  cpu = 500
  memeory = 512
}
// after
resources {
  cpu = 500
  memory = 512
}
Defensive patterns

Strategy: validation

Validate before calling

if errs := helper.UnusedKeys(cfgStruct); errs != nil {
    return fmt.Errorf("config contains unknown fields: %w", errs)
}

Prevention

When it happens

Trigger: Calling helper.UnusedKeys (or recursive unusedKeysImpl) on a decoded config struct whose 'unused keys' field is non-empty, i.e. the source map/HCL contained keys that did not map to any struct field.

Common situations: Users write extra attributes in a job/task config stanza; after decoding, UnusedKeys is run as a strictness check and rejects the config instead of silently ignoring the keys.

Related errors


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