AWS Error Guide: 'DeleteConflict' — Detach Dependencies Before Deleting an IAM Role or User
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
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
DeleteRolefails withmust detach all policies firstormust remove role from all instance profiles first.DeleteUserfails referencing access keys, login profile, MFA devices, signing certificates, or group memberships.DeletePolicyfails 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
destroyhandles 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-policyand 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:
- Managed policies still attached (detach them).
- Inline policies still embedded (delete, not detach, them).
- The role still belongs to an instance profile.
- A user still has access keys, MFA, a login profile, or group memberships.
- 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.
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?
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.