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

  1. Check auth server logs to find which access list and which role position (member/owner/audit) references the role.
  2. Update the access list (access_lists UpdateAccessList) to remove or replace the role reference, then retry DeleteRole.
  3. 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

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


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/655b061f9c327e71. Report an issue: GitHub.