{"record":{"id":"80be12659662f6a4","repo":"hashicorp/nomad","slug":"unable-to-release-dynamic-workload-user-w","errorCode":null,"errorMessage":"unable to release dynamic workload user: %w","messagePattern":"unable to release dynamic workload user: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/dynamic_users_hook.go","lineNumber":114,"sourceCode":"\t// if the task driver does not support the DWU capability, nothing to do\n\tif !h.usable {\n\t\treturn nil\n\t}\n\n\t// if we did not store a user for this task; nothing to release\n\tuser, exists := request.ExistingState[dynamicUsersStateKey]\n\tif !exists {\n\t\treturn nil\n\t}\n\n\t// otherwise we need to release the UGID back to the pool\n\th.lock.Lock()\n\tdefer h.lock.Unlock()\n\n\t// parse the UID/GID from the pseudo username\n\tugid, err := dynamic.Parse(user)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to release dynamic workload user: %w\", err)\n\t}\n\n\t// release the UID/GID to the pool\n\tif err = h.pool.Release(ugid); err != nil {\n\t\treturn fmt.Errorf(\"unable to release dynamic workload user: %w\", err)\n\t}\n\n\th.logger.Trace(\"released dynamic workload user\", \"ugid\", ugid)\n\treturn nil\n}\n","sourceCodeStart":96,"sourceCodeEnd":125,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/dynamic_users_hook.go#L96-L125","documentation":"The dynamic_users_hook Stop method releases the workload's dynamic (pseudo) username back to a UID/GID pool. Before releasing, it parses the username back into a ugid via dynamic.Parse; if parsing fails, it returns 'unable to release dynamic workload user' wrapping that error. The user string was not generated by the pool or is malformed.","triggerScenarios":"dynamic.Parse(user) fails in Stop because the stored/derived pseudo-username is empty, has an unexpected format, or was not created by the dynamic user manager (e.g. hook state lost or a task configured without dynamic users but hook runs anyway).","commonSituations":"Client state directory corrupted or hook state missing so the username is empty/garbage; upgrading Nomad where username scheme changed; a task that never created a dynamic user still calling Stop.","solutions":["Check the wrapped error from dynamic.Parse to see why the username is invalid","Verify the hook's stored state (username) for the allocation is intact in the client data dir","Confirm the task actually uses dynamic workload users ( userns/config) before release","If the user was never created, tolerate/skip the release instead of failing Stop","On persistent corruption, clean the client state dir for that alloc and restart the client"],"exampleFix":"// before: unconditionally parse whatever user string exists\nugid, err := dynamic.Parse(user)\n// after: guard before parse\nif user == \"\" { return nil }\nugid, err := dynamic.Parse(user)","handlingStrategy":"try-catch","validationCode":"// only attempt release when a username was actually created\nif user == \"\" {\n    return nil // nothing to release\n}\nif _, err := dynamic.Parse(user); err != nil {\n    log.Printf(\"skip release: stored user %q is not a dynamic user\", user)\n    return nil\n}","typeGuard":"func isDynamicUser(user string) bool {\n    _, err := dynamic.Parse(user)\n    return err == nil\n}","tryCatchPattern":"if err := hook.Stop(ctx, req); err != nil {\n    var inner error\n    if errors.As(err, &inner) && strings.Contains(err.Error(), \"unable to release dynamic workload user\") {\n        log.Printf(\"dynamic user release failed (non-fatal for task cleanup): %v\", err)\n    }\n}","preventionTips":["Persist hook state (generated username) in the client state dir","Skip release when the task never created a dynamic user","Treat Stop-time release failures as warnings, not allocation failures","Version/validate username format across Nomad upgrades"],"tags":["linux","dynamic-users","nomad"],"backgroundTag":"dynamic-user-release-failed","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"}