{"record":{"id":"79a739f86b18c596","repo":"gravitational/teleport","slug":"managed-host-users-can-not-be-converted-to-or-from","errorCode":null,"errorMessage":"managed host users can not be converted to or from a static host user","messagePattern":"managed host users can not be converted to or from a static host user","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/srv/usermgmt.go","lineNumber":292,"sourceCode":"\tif errors.Is(err, host.ErrInvalidSudoers) {\n\t\tu.log.WarnContext(context.Background(), \"Invalid sudoers entry. If using a login managed by a static host user resource, inspect its configured sudoers field for invalid entries. Otherwise, inspect the host_sudoers field for roles targeting this host.\", \"error\", err, \"host_username\", name)\n\t\treturn trace.BadParameter(\"invalid sudoers entry for login %q, inspect roles' host_sudoers field or static host user's sudoers field for invalid syntax\", name)\n\t}\n\treturn trace.Wrap(err)\n}\n\nfunc (u *HostSudoersManagement) RemoveSudoers(name string) error {\n\tif err := u.backend.RemoveSudoersFile(name); err != nil {\n\t\treturn trace.Wrap(err)\n\t}\n\treturn nil\n}\n\n// errUnmanagedUser is returned when attempting to modify or interact with a user that is not managed by Teleport.\nvar errUnmanagedUser = errors.New(\"user not managed by teleport\")\n\n// errStaticConversion is returned when attempting to convert a managed host user to or from a static host user\nvar errStaticConversion = errors.New(\"managed host users can not be converted to or from a static host user\")\n\nfunc (u *HostUserManagement) updateUser(hostUser HostUser, ui *decisionpb.HostUsersInfo) error {\n\tctx := u.ctx\n\tlog := u.log.With(\n\t\t\"host_username\", hostUser.Name,\n\t\t\"mode\", ui.GetMode(),\n\t\t\"uid\", hostUser.UID,\n\t\t\"gid\", hostUser.GID,\n\t)\n\n\tif ui.GetMode() == decisionpb.HostUserMode_HOST_USER_MODE_KEEP {\n\t\t_, hasKeepGroup := hostUser.Groups[apiconstants.TeleportKeepGroup]\n\t\tif !hasKeepGroup {\n\t\t\thome, err := u.backend.GetDefaultHomeDirectory(hostUser.Name)\n\t\t\tif err != nil {\n\t\t\t\treturn trace.Wrap(err)\n\t\t\t}\n","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/lib/srv/usermgmt.go#L274-L310","documentation":"errStaticConversion is returned when ResolveGroups detects an attempt to convert a host user between auto-provisioned (managed) mode and static host user mode. Teleport forbids in-place conversion to prevent unexpected account state changes; the caller (UpsertUser) logs and aborts the update.","triggerScenarios":"ResolveGroups (lib/srv/usermgmt.go:788) sees a user currently in static mode while the role/config declares it managed, or vice versa: (inStaticMode && managedUser) || (!inStaticMode && staticUser).","commonSituations":"Operator flips a role's host user mode (host_users mode static vs dynamic) for users that already exist on servers; migrating hosts between static host user definitions and auto-provisioning without cleanup.","solutions":["Remove the existing host user on the server and let Teleport recreate it in the desired mode","Align the role's host user mode with the existing user's current mode instead of converting","Plan migration explicitly: switch mode, then manually reconcile accounts on hosts"],"exampleFix":"// before: flipping mode for existing user\nhost_users:\n  mode: static\n// after: delete existing managed user on host first, then apply static mode,\n// or keep mode consistent with existing user state\nhost_users:\n  mode: keep  # unchanged until accounts reconciled","handlingStrategy":"validation","validationCode":"// ensure the user's current mode matches the target mode before upsert\ncurrentlyStatic := isStaticHostUser(hostUser)\ntargetStatic := ui.GetMode() == decisionpb.HostUsersMode_HOST_USERS_MODE_STATIC\nif currentlyStatic != targetStatic {\n    return trace.BadParameter(\"recreate user %s to change static/managed mode\", hostUser.Name)\n}","typeGuard":"func isStaticConversionErr(err error) bool { return errors.Is(err, errStaticConversion) }","tryCatchPattern":"if _, err := ResolveGroups(log, hostUser, ui, options.takeOwnership); err != nil {\n    if errors.Is(err, errStaticConversion) {\n        log.DebugContext(ctx, \"cannot convert between auto-provisioned and static host users\")\n        return nil\n    }\n    return trace.Wrap(err)\n}","preventionTips":["Keep host user mode consistent per user across role updates","Delete and recreate the account when switching modes","Document mode changes as migration operations, not in-place edits"],"tags":["host-users","static-host-users","user-management"],"backgroundTag":"host-user-mode-conversion","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}