AWS Error: 'is not authorized to perform: sts:AssumeRole' — Cause, Fix, and Troubleshooting Guide
Fix the STS AccessDenied 'is not authorized to perform: sts:AssumeRole' error: trust policy principals, missing identity permissions, external IDs, and MFA.
- #aws
- #cloud
- #troubleshooting
- #errors
- #iam
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
Assuming an IAM role requires two independent allows: the role’s trust policy must permit your principal to assume it, and your identity policy must grant sts:AssumeRole on that role. If either side is missing (or a condition like ExternalId/MFA isn’t satisfied), STS returns AccessDenied on AssumeRole. The error names the calling principal and the target role, which pins down which side to fix.
You will see it surface from the CLI, an SDK, or cross-account tooling:
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::111122223333:user/dev is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::444455556666:role/CrossAccountDeploy
It occurs whenever role chaining, cross-account access, CI role assumption, or aws sts assume-role runs without both allows and any required conditions in place.
Symptoms
aws sts assume-role(or an SDK/Terraformassume_roleblock) fails withis not authorized to perform: sts:AssumeRole.- Cross-account access works for one principal but not another.
- It started after tightening a trust policy, rotating to a new CI role, or adding an
ExternalId/MFA condition. aws sts get-caller-identitysucceeds (base creds are fine) but the assume fails.
aws sts assume-role \
--role-arn arn:aws:iam::444455556666:role/CrossAccountDeploy \
--role-session-name deploy
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::111122223333:user/dev is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::444455556666:role/CrossAccountDeploy
Common Root Causes
1. The role’s trust policy doesn’t allow your principal
The target role’s AssumeRolePolicyDocument doesn’t list your account/user/role as a trusted Principal.
2. Your identity policy lacks sts:AssumeRole
Your side has no Allow for sts:AssumeRole on that role ARN.
3. A missing or mismatched ExternalId
The trust policy requires sts:ExternalId and you didn’t pass --external-id (or passed the wrong value).
4. An unmet MFA condition
The trust policy requires aws:MultiFactorAuthPresent, but the session has no MFA.
5. A permission boundary or SCP blocks the assume
An SCP or a permission boundary on your principal denies sts:AssumeRole regardless of the identity policy.
6. Wrong role ARN or path
A typo, wrong account ID, or an IAM path mismatch means the target isn’t what you think.
How to diagnose
Step 1: Confirm who you actually are
aws sts get-caller-identity --query Arn --output text
This is the exact principal that must appear (directly or via account root) in the trust policy.
Step 2: Read the target role’s trust policy
aws iam get-role --role-name CrossAccountDeploy \
--query 'Role.AssumeRolePolicyDocument' --output json
Check the Principal matches your Step 1 ARN and note any Condition (sts:ExternalId, MFA).
Step 3: Simulate your identity-side permission
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::111122223333:user/dev \
--action-names sts:AssumeRole \
--resource-arns arn:aws:iam::444455556666:role/CrossAccountDeploy \
--query 'EvaluationResults[].[EvalDecision]' --output text
implicitDeny means you’re missing the identity-side allow; explicitDeny points at an SCP/boundary.
Fixes
Add your principal to the role’s trust policy
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:role/ci-deployer" },
"Action": "sts:AssumeRole"
}
Grant sts:AssumeRole on your identity side
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::444455556666:role/CrossAccountDeploy"
}
Pass the required ExternalId / MFA
aws sts assume-role --role-arn arn:aws:iam::444455556666:role/CrossAccountDeploy \
--role-session-name deploy --external-id REDACTED-EXTID \
--serial-number arn:aws:iam::111122223333:mfa/dev --token-code 123456
What to watch out for
- Both sides must allow the assume — fixing only the trust policy or only the identity policy leaves it broken.
- Trusting an account root (
arn:aws:iam::111122223333:root) in the trust policy also requires each principal in that account to havests:AssumeRoleon their identity side. ExternalIdis case-sensitive and must match exactly; it’s the standard defense for third-party cross-account roles.- An
explicitDenyfrom the simulator means an SCP or permission boundary — no amount of identity/trust editing overrides it until that’s changed.
Related
- AWS Error: ‘AccessDenied … not authorized to perform’ — the general IAM authorization failure pattern.
- AWS Error: SCP explicit deny — Organizations SCPs that block the assume regardless of IAM.
- AWS Error: EKS ‘You must be logged in to the server (Unauthorized)’ — a common downstream effect of a failed role assumption.
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.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2mount: wrong fs type, bad option, bad superblock
- 3Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 4Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block
- 5Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 6Too many levels of symbolic links
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.