{"record":{"id":"29ba18de12968dab","repo":"hashicorp/nomad","slug":"users-must-not-be-nil","errorCode":null,"errorMessage":"users must not be nil","messagePattern":"users must not be nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/config/users.go","lineNumber":64,"sourceCode":"}\n\n// Equal returns whether u and o are the same.\nfunc (u *UsersConfig) Equal(o *UsersConfig) bool {\n\tif u == nil || o == nil {\n\t\treturn u == o\n\t}\n\tswitch {\n\tcase !pointer.Eq(u.MinDynamicUser, o.MinDynamicUser):\n\t\treturn false\n\tcase !pointer.Eq(u.MaxDynamicUser, o.MaxDynamicUser):\n\t\treturn false\n\tdefault:\n\t\treturn true\n\t}\n}\n\nvar (\n\terrUsersUnset            = errors.New(\"users must not be nil\")\n\terrDynamicUserMinUnset   = errors.New(\"dynamic_user_min must be set\")\n\terrDynamicUserMinInvalid = errors.New(\"dynamic_user_min must not be negative\")\n\terrDynamicUserMaxUnset   = errors.New(\"dynamic_user_max must be set\")\n\terrDynamicUserMaxInvalid = errors.New(\"dynamic_user_max must not be negative\")\n)\n\n// Validate whether UsersConfig is valid.\n//\n// Note that -1 is a valid value for min/max dynamic users, as this is used\n// to indicate the dynamic workload users feature should be disabled.\nfunc (u *UsersConfig) Validate() error {\n\tif u == nil {\n\t\treturn errUsersUnset\n\t}\n\tif u.MinDynamicUser == nil {\n\t\treturn errDynamicUserMinUnset\n\t}\n\tif *u.MinDynamicUser < -1 {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/config/users.go#L46-L82","documentation":"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).","triggerScenarios":"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.","commonSituations":"Agents running with a config file that lacks the users stanza; programmatic construction of AgentConfig without setting Users; unit tests asserting nil-config behavior.","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."],"exampleFix":"// before\nvar cfg *config.UsersConfig // nil\nerr := cfg.Validate() // users must not be nil\n\n// after\ncfg := &config.UsersConfig{\n    MinDynamicUser: ptrOf(-1),\n    MaxDynamicUser: ptrOf(-1),\n}\nerr := cfg.Validate() // nil","handlingStrategy":"validation","validationCode":"if cfg.Users == nil {\n    return fmt.Errorf(\"agent config is missing the users block\")\n}","typeGuard":"func usersConfigOK(u *config.UsersConfig) bool { return u != nil }","tryCatchPattern":"if err := usersCfg.Validate(); err != nil {\n    if errors.Is(err, errUsersUnset) {\n        return fmt.Errorf(\"users section absent from agent config\")\n    }\n    return err\n}","preventionTips":["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."],"tags":["nomad","agent-config","validation"],"backgroundTag":"nil-config-validation","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"}