gravitational/teleport · error
failed to delete a role that is still in use by an access li
Error message
failed to delete a role that is still in use by an access list, check the system server logs for more details
What it means
DeleteRole refuses deletion when the role is used by an access list. errDeleteRoleAccessList is returned at two points (lib/auth/access.go:162 and :170) covering different access-list role positions (e.g. owner/grant roles and audit roles), with specifics logged server-side.
Source
Thrown at lib/auth/access.go:108
Metadata: apievents.Metadata{
Type: events.RoleCreatedEvent,
Code: events.RoleCreatedCode,
},
UserMetadata: authz.ClientUserMetadata(ctx),
ResourceMetadata: apievents.ResourceMetadata{
Name: role.GetName(),
},
ConnectionMetadata: authz.ConnectionMetadata(ctx),
}); err != nil {
a.logger.WarnContext(ctx, "Failed to emit role create event.", "error", err)
}
return upserted, nil
}
var (
errDeleteRoleUser = errors.New("failed to delete a role that is still in use by a user, check the system server logs for more details")
errDeleteRoleCA = errors.New("failed to delete a role that is still in use by a certificate authority, check the system server logs for more details")
errDeleteRoleAccessList = errors.New("failed to delete a role that is still in use by an access list, check the system server logs for more details")
)
// DeleteRole deletes a role and emits a related audit event.
func (a *Server) DeleteRole(ctx context.Context, name string) error {
// check if this role is used by CA or Users
users, err := a.Services.GetUsers(ctx, false)
if err != nil {
return trace.Wrap(err)
}
for _, u := range users {
if slices.Contains(u.GetRoles(), name) {
// Mask the actual error here as it could be used to enumerate users
// within the system.
a.logger.WarnContext(
ctx, "Failed to delete role: role is still in use by a user",
"role", name, "user", u.GetName(),
)
return trace.Wrap(errDeleteRoleUser)View on GitHub (pinned to 1283425b60)
Solutions
- Check auth server logs to find which access list and which role position (member/owner/audit) references the role.
- Update the access list (access_lists UpdateAccessList) to remove or replace the role reference, then retry DeleteRole.
- If the access list itself is obsolete, delete the access list first, then the role.
Defensive patterns
Strategy: type-guard
Validate before calling
lists, _ := accessLists.ListAccessLists(ctx)
for _, l := range lists { if usesRole(l, roleName) { return fmt.Errorf("role %q used by access list %q", roleName, l.GetName()) } } Type guard
if errors.Is(err, auth.ErrDeleteRoleAccessList) { /* role in use by an access list */ } Try / catch
err := authServer.DeleteRole(ctx, roleName)
if errors.Is(err, auth.ErrDeleteRoleAccessList) {
return trace.BadParameter("remove the role from all access lists (member/owner/audit) before deleting it")
} Prevention
- Enumerate access lists and check member, owner, and audit role fields before deleting a role.
- Update access lists via UpdateAccessList to swap roles atomically before removal.
- Centralize role cleanup scripts so they always process access lists alongside users and CAs.
When it happens
Trigger: Calling Server.DeleteRole(ctx, name) while any access list references the role as a member role, owner role, or audit role during the access-list scan.
Common situations: Cleanup of legacy roles while access-list automation still grants them; deleting a role that an access list uses for review/audit assignments; tenant onboarding scripts that create access lists pointing at soon-to-be-deleted roles.
Related errors
- failed to delete a role that is still in use by a user, chec
- failed to delete a role that is still in use by a certificat
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/655b061f9c327e71.
Report an issue: GitHub.