{"record":{"id":"66e163f6b2665e85","repo":"hashicorp/nomad","slug":"running-as-user-q-is-disallowed","errorCode":null,"errorMessage":"running as user %q is disallowed","messagePattern":"running as user %q is disallowed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/validate_hook.go","lineNumber":57,"sourceCode":"\t}\n\n\tresp.Done = true\n\treturn nil\n}\n\nfunc validateTask(task *structs.Task, taskEnv *taskenv.TaskEnv, conf *config.Config) error {\n\tvar mErr multierror.Error\n\n\t// Validate the user\n\t// COMPAT(1.0) uses inclusive language. blacklist is kept for backward compatilibity.\n\tunallowedUsers := conf.ReadStringListAlternativeToMapDefault(\n\t\t[]string{\"user.denylist\", \"user.blacklist\"},\n\t\tconfig.DefaultUserDenylist,\n\t)\n\tcheckDrivers := conf.ReadStringListToMapDefault(\"user.checked_drivers\", config.DefaultUserCheckedDrivers)\n\tif _, driverMatch := checkDrivers[task.Driver]; driverMatch {\n\t\tif _, unallowed := unallowedUsers[task.User]; unallowed {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"running as user %q is disallowed\", task.User))\n\t\t}\n\t}\n\n\t// Validate the Service names once they're interpolated\n\tfor _, service := range task.Services {\n\t\tname := taskEnv.ReplaceEnv(service.Name)\n\t\tif err := service.ValidateName(name); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"service (%s) failed validation: %v\", name, err))\n\t\t}\n\t}\n\n\tif len(mErr.Errors) == 1 {\n\t\treturn mErr.Errors[0]\n\t}\n\treturn mErr.ErrorOrNil()\n}\n","sourceCodeStart":39,"sourceCodeEnd":74,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/validate_hook.go#L39-L74","documentation":"Nomad's validate hook enforces a user denylist for drivers on the checked_drivers list. If the task's User resolves to a user present in the configured denylist and the task's driver is one being checked, task validation fails and the task never starts. This is a security guard against running tasks as privileged or forbidden accounts.","triggerScenarios":"task.User is set (or defaults) to a user in user.denylist (default includes root) while the task's driver is in user.checked_drivers (default: docker, exec, qemu, etc.), evaluated during validateTask in Prestart.","commonSituations":"Jobs specifying user = \"root\" on docker/exec drivers; agent config where user.denylist was tightened after the job was written; legacy jobs predating the enforcement.","solutions":["Change the task's user field to an allowed non-privileged user","Adjust user.denylist/user.checked_drivers in the client config if policy legitimately permits the user (with caution)","Remove the user block so the driver default user applies","Re-run the job after fixing"],"exampleFix":"// before\ntask \"web\" {\n  driver = \"docker\"\n  user   = \"root\"\n}\n// after\ntask \"web\" {\n  driver = \"docker\"\n  user   = \"nobody\"\n}","handlingStrategy":"validation","validationCode":"// pre-validate the user against the denylist before submit\nunallowedUsers := conf.ReadStringListToMapDefault(\"user.denylist\", config.DefaultUserDenylist)\ncheckDrivers := conf.ReadStringListToMapDefault(\"user.checked_drivers\", config.DefaultUserCheckedDrivers)\nif checkDrivers[task.Driver] && unallowedUsers[task.User] {\n    return fmt.Errorf(\"user %q disallowed for driver %q\", task.User, task.Driver)\n}","typeGuard":null,"tryCatchPattern":"if err := validateTask(task, conf); err != nil {\n    // multierror: inspect entries for the user enforcement failure\n    for _, e := range err.Errors {\n        if strings.Contains(e.Error(), \"running as user\") {\n            return fmt.Errorf(\"fix task.user in job spec: %w\", e)\n        }\n    }\n    return err\n}","preventionTips":["Never set user = \"root\" unless the denylist policy explicitly permits it","Review job specs against the client's user.denylist when tightening policy","Document which drivers are in user.checked_drivers for your fleet","Run nomad job validate in CI to catch this before deploy"],"tags":["security","validation","user","nomad"],"backgroundTag":"user-denylist-violation","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"}