Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AWS with AI By James Joyner IV · · 8 min read Last reviewed Jul 2026

AWS Error Guide: 'DeleteConflict' — Detach Dependencies Before Deleting an IAM Role or User

Quick answer

Fix DeleteConflict in AWS IAM: detach managed policies, delete inline policies, and remove instance profiles, access keys, and MFA so a role or user deletes.

  • #aws
  • #cloud
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this AWS with AI error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

IAM refuses to delete a role, user, group, or policy while other entities still depend on it. Attempting the delete returns DeleteConflict, telling you the identity “must be removed from” or “cannot be deleted because it still has” attached resources. This protects against orphaning an instance profile, a group membership, or a policy attachment that something still relies on — but it means deleting an identity is a multi-step teardown, not a single call.

You will see it from the CLI or SDK:

An error occurred (DeleteConflict) when calling the DeleteRole operation: Cannot delete entity, must detach all policies first.

The user variant enumerates a different set of dependencies:

An error occurred (DeleteConflict) when calling the DeleteUser operation: Cannot delete entity, must delete access keys first.

It occurs whenever automation or an operator tries to delete an IAM entity that still has attached managed policies, inline policies, an instance profile, access keys, login profile, MFA devices, group memberships, or (for a policy) live attachments.

Symptoms

  • DeleteRole fails with must detach all policies first or must remove role from all instance profiles first.
  • DeleteUser fails referencing access keys, login profile, MFA devices, signing certificates, or group memberships.
  • DeletePolicy fails because the managed policy is still attached to a role/user/group.
  • A Terraform/CloudFormation destroy hangs or errors on an IAM resource with dependency conflicts.
aws iam delete-role --role-name legacy-batch-role
An error occurred (DeleteConflict) when calling the DeleteRole operation: Cannot delete entity, must detach all policies first.

Common Root Causes

1. Managed policies still attached

The role or user still has AWS-managed or customer-managed policies attached, which must be detached first.

aws iam list-attached-role-policies --role-name legacy-batch-role \
  --query 'AttachedPolicies[].PolicyArn' --output text
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess	arn:aws:iam::REDACTED:policy/batch-writer

Both must be detached before the role deletes.

2. Inline policies still present

Inline policies are embedded in the entity and are not “detached” — they must be deleted.

aws iam list-role-policies --role-name legacy-batch-role --query 'PolicyNames' --output text
inline-scratch-access

The inline policy blocks deletion until it is removed.

3. The role is still in an instance profile

A role attached to an instance profile cannot be deleted until it is removed from that profile.

aws iam list-instance-profiles-for-role --role-name legacy-batch-role \
  --query 'InstanceProfiles[].InstanceProfileName' --output text
legacy-batch-profile

Remove the role from the profile (and delete the profile if unused) first.

4. A user still has access keys, login profile, or MFA

Users carry credentials that must all be deleted before the user can go.

aws iam list-access-keys --user-name contractor-jane --query 'AccessKeyMetadata[].AccessKeyId' --output text
aws iam list-mfa-devices --user-name contractor-jane --query 'MFADevices[].SerialNumber' --output text
AKIAREDACTED
arn:aws:iam::REDACTED:mfa/contractor-jane

Both the key and the MFA device block deletion.

5. A managed policy is still attached somewhere

DeletePolicy fails while any entity still references it, and its non-default versions must be removed too.

aws iam list-entities-for-policy --policy-arn arn:aws:iam::REDACTED:policy/batch-writer \
  --query '[PolicyRoles,PolicyUsers,PolicyGroups]' --output text
legacy-batch-role	None	None

The policy is still attached to legacy-batch-role, so it cannot be deleted yet.

Diagnostic Workflow

Step 1: Enumerate every dependency on the entity

ROLE=legacy-batch-role
aws iam list-attached-role-policies --role-name "$ROLE" --query 'AttachedPolicies[].PolicyArn' --output text
aws iam list-role-policies --role-name "$ROLE" --query 'PolicyNames' --output text
aws iam list-instance-profiles-for-role --role-name "$ROLE" --query 'InstanceProfiles[].InstanceProfileName' --output text

This lists the three things that block a role delete: managed attachments, inline policies, and instance profiles.

Step 2: For a user, list all credentials and memberships

U=contractor-jane
aws iam list-access-keys --user-name "$U" --query 'AccessKeyMetadata[].AccessKeyId' --output text
aws iam list-mfa-devices --user-name "$U" --query 'MFADevices[].SerialNumber' --output text
aws iam list-groups-for-user --user-name "$U" --query 'Groups[].GroupName' --output text
aws iam get-login-profile --user-name "$U" 2>/dev/null && echo "has console login"

Each of these must be removed before DeleteUser succeeds.

Step 3: For a policy, find what still attaches it

aws iam list-entities-for-policy --policy-arn <POLICY_ARN> \
  --query '[PolicyRoles[].RoleName,PolicyUsers[].UserName,PolicyGroups[].GroupName]' --output text

Detach from every listed entity, and delete any non-default versions, before DeletePolicy.

Step 4: Confirm nothing live still uses the identity

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=ResourceName,AttributeValue=legacy-batch-role \
  --query 'Events[?EventName==`AssumeRole`]|[0].EventTime' --output text

Check recent AssumeRole/GetSessionToken activity so you do not delete a role something still assumes.

Example Root Cause Analysis

A cleanup script that decommissioned old service roles failed on DeleteRole with must detach all policies first, even though the operator had “removed the policies” in the console.

Enumerating dependencies showed the managed policies were gone but an inline policy and an instance profile remained:

aws iam list-attached-role-policies --role-name legacy-batch-role --query 'AttachedPolicies' --output text
aws iam list-role-policies --role-name legacy-batch-role --query 'PolicyNames' --output text
aws iam list-instance-profiles-for-role --role-name legacy-batch-role --query 'InstanceProfiles[].InstanceProfileName' --output text

inline-scratch-access
legacy-batch-profile

The console’s “detach” only handled managed policies; the inline policy and instance profile were invisible to that action. The teardown, in order, deleted cleanly:

aws iam delete-role-policy --role-name legacy-batch-role --policy-name inline-scratch-access
aws iam remove-role-from-instance-profile --instance-profile-name legacy-batch-profile --role-name legacy-batch-role
aws iam delete-instance-profile --instance-profile-name legacy-batch-profile
aws iam delete-role --role-name legacy-batch-role && echo "deleted"

The durable fix was a teardown script that always enumerates and removes managed policies, inline policies, and instance profiles in that order before the delete.

Prevention Best Practices

  • Script IAM teardown to enumerate and remove all dependencies (managed + inline policies, instance profiles for roles; keys, MFA, login profile, group memberships for users) before the delete call.
  • Prefer CloudFormation/Terraform to own IAM entities so destroy handles the dependency order for you.
  • Remember inline policies are deleted, not detached — the console’s detach action does not touch them.
  • Delete roles and their instance profiles as a pair; leaving one orphans the other and blocks reuse of the name.
  • Before deleting a policy, run list-entities-for-policy and detach everywhere, and remove non-default versions first.

Quick Command Reference

# Role teardown, correct order
aws iam list-attached-role-policies --role-name <role> --query 'AttachedPolicies[].PolicyArn' --output text \
  | tr '\t' '\n' | xargs -I{} aws iam detach-role-policy --role-name <role> --policy-arn {}
aws iam list-role-policies --role-name <role> --query 'PolicyNames' --output text \
  | tr '\t' '\n' | xargs -I{} aws iam delete-role-policy --role-name <role> --policy-name {}
aws iam list-instance-profiles-for-role --role-name <role> --query 'InstanceProfiles[].InstanceProfileName' --output text \
  | tr '\t' '\n' | xargs -I{} aws iam remove-role-from-instance-profile --instance-profile-name {} --role-name <role>
aws iam delete-role --role-name <role>

# User credentials that block DeleteUser
aws iam list-access-keys --user-name <user>
aws iam list-mfa-devices --user-name <user>
aws iam list-groups-for-user --user-name <user>

# What still attaches a managed policy
aws iam list-entities-for-policy --policy-arn <arn>

Conclusion

DeleteConflict means the IAM entity still has dependencies IAM will not orphan. The usual root causes:

  1. Managed policies still attached (detach them).
  2. Inline policies still embedded (delete, not detach, them).
  3. The role still belongs to an instance profile.
  4. A user still has access keys, MFA, a login profile, or group memberships.
  5. A managed policy is still attached to some entity (or has non-default versions).

Enumerate every dependency first, remove them in order, then delete — or let IaC manage the lifecycle so the dependency order is handled for you.

Free download · 368-page PDF

Fixed it? Get 500 AWS with AI & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.