hashicorp/nomad · error
users must not be nil
Error message
users must not be nil
What it means
errUsersUnset is the sentinel error returned by UsersConfig.Validate() when the entire UsersConfig pointer is nil. Nomad's agent config requires a users section (for dynamic workload users) to be present as an object; a nil config means it was never initialized. The error lets callers test with errors.Is(err, errUsersUnset).
Source
Thrown at nomad/structs/config/users.go:64
}
// Equal returns whether u and o are the same.
func (u *UsersConfig) Equal(o *UsersConfig) bool {
if u == nil || o == nil {
return u == o
}
switch {
case !pointer.Eq(u.MinDynamicUser, o.MinDynamicUser):
return false
case !pointer.Eq(u.MaxDynamicUser, o.MaxDynamicUser):
return false
default:
return true
}
}
var (
errUsersUnset = errors.New("users must not be nil")
errDynamicUserMinUnset = errors.New("dynamic_user_min must be set")
errDynamicUserMinInvalid = errors.New("dynamic_user_min must not be negative")
errDynamicUserMaxUnset = errors.New("dynamic_user_max must be set")
errDynamicUserMaxInvalid = errors.New("dynamic_user_max must not be negative")
)
// Validate whether UsersConfig is valid.
//
// Note that -1 is a valid value for min/max dynamic users, as this is used
// to indicate the dynamic workload users feature should be disabled.
func (u *UsersConfig) Validate() error {
if u == nil {
return errUsersUnset
}
if u.MinDynamicUser == nil {
return errDynamicUserMinUnset
}
if *u.MinDynamicUser < -1 {View on GitHub (pinned to 482b49bf1a)
Solutions
- Provide a users block in the agent configuration (or initialize the UsersConfig struct in code) before validation.
- If the section is optional in your setup, ensure config decoding still allocates a non-nil UsersConfig with defaults.
- In tests/automation, match the sentinel with errors.Is(err, structs/config errUsersUnset) to distinguish it from other validation errors.
Example fix
// before
var cfg *config.UsersConfig // nil
err := cfg.Validate() // users must not be nil
// after
cfg := &config.UsersConfig{
MinDynamicUser: ptrOf(-1),
MaxDynamicUser: ptrOf(-1),
}
err := cfg.Validate() // nil Defensive patterns
Strategy: validation
Validate before calling
if cfg.Users == nil {
return fmt.Errorf("agent config is missing the users block")
} Type guard
func usersConfigOK(u *config.UsersConfig) bool { return u != nil } Try / catch
if err := usersCfg.Validate(); err != nil {
if errors.Is(err, errUsersUnset) {
return fmt.Errorf("users section absent from agent config")
}
return err
} Prevention
- Always include a users block in agent configs when the feature applies.
- Use config decoding that applies defaults so UsersConfig is never left nil.
- Test nil-config paths with errors.Is against errUsersUnset.
When it happens
Trigger: Calling (*UsersConfig)(nil).Validate(), or the agent config validation path where the `users` block was omitted/failed to decode so the *UsersConfig field is nil at validation time.
Common situations: Agents running with a config file that lacks the users stanza; programmatic construction of AgentConfig without setting Users; unit tests asserting nil-config behavior.
Related errors
- dynamic_user_min must be set
- dynamic_user_min must not be negative
- dynamic_user_max must be set
- dynamic_user_max must not be negative
- missing secret ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/29ba18de12968dab.
Report an issue: GitHub.