not authorized to perform: iam:PassRole
Fix iam:PassRole denied: add iam:PassRole on the exact role ARN with an iam:PassedToService condition. Covers EC2 instance profiles and ECS task roles.
An error occurred (AccessDenied) when calling the RunInstances operation: User: arn:aws:iam::123456789012:user/dev is no
Incident Overview
Fix iam:PassRole denied: add iam:PassRole on the exact role ARN with an iam:PassedToService condition. Covers EC2 instance profiles and ECS task roles.
medium fix·5 min read
By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026
An error occurred (AccessDenied) when calling the RunInstances operation: User: arn:aws:iam::123456789012:user/dev is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789012:role/app-instance-role User: arn:aws:sts::123456789012:assumed-role/deploy/session is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789012:role/ecsTaskExecutionRole because no identity-based policy allows the iam:PassRole action
Do this first3 steps
Run these in order. Each one tells you what its output means before you change anything.
• Read which role you are being refused permission to pass
The error names two ARNs: the identity making the call, and the role it wants to pass. PassRole must be granted on the second, in the identity policy of the first.
• Grant PassRole scoped to that specific role
Put that exact ARN in a Resource list rather than using a wildcard. PassRole on * lets the holder attach any role in the account to a resource they control, which is a full privilege escalation path.
• Confirm the target role trusts the service you are passing it to
PassRole permits handing the role over; the role's own trust policy decides whether the service may assume it. A role that does not trust ec2.amazonaws.com cannot be used as an instance profile even with PassRole granted.
iam:PassRole is not an action against IAM. It is a permission check AWS runs when you hand a role to a service: launching an EC2 instance with an instance profile, creating a Lambda with an execution role, registering an ECS task definition with a task role.
It exists because otherwise anyone who could create a resource could grant it any permissions in the account. Create a Lambda with an admin role attached, invoke it, and you are admin. PassRole is the check that stops that.
So the permission to create the resource and the permission to pass the role are deliberately separate.
aws sts get-caller-identity
Read the two ARNs
The user needs iam:PassRole on the role. That grant goes in the user's own identity policy, not in the role.
User: arn:aws:iam::123456789012:user/dev is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789012:role/app-instance-role
Grant it, scoped
Never "Resource": "*" on PassRole. That is a full escalation path: the holder can attach any role in the account, including an administrator role, to a resource they control and then use it.
For several roles, list them, or use a path or naming convention:
Creating your roles under a path such as /app/ makes this pattern clean and auditable.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/app-instance-role"
}
]
}Constrain which service it can be passed to
iam:PassedToService limits the grant to one service:
Now the role can be passed to ECS tasks and not to EC2 or Lambda. This is worth adding: it means a role intended for one service cannot be repurposed onto another where its permissions might combine differently.
Service principals you will use most:
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"Condition": {
"StringEquals": { "iam:PassedToService": "ecs-tasks.amazonaws.com" }
}
}PassRole is not enough on its own
Two separate checks have to pass:
A role that does not trust ec2.amazonaws.com cannot be an instance profile even when PassRole is granted, and the error you get is different and less clear.
aws iam get-role --role-name app-instance-role \ --query 'Role.AssumeRolePolicyDocument'
EC2 also needs the instance profile
For EC2 specifically there is a third thing. An instance profile is a container around the role, and older tooling requires both permissions:
A role created in the console gets an instance profile of the same name automatically. One created with the CLI or Terraform does not; you create aws_iam_instance_profile separately, and forgetting it produces a confusing failure at launch.
{
"Effect": "Allow",
"Action": ["iam:PassRole", "ec2:AssociateIamInstanceProfile", "ec2:ReplaceIamInstanceProfileAssociation"],
"Resource": "*"
}ECS needs it twice
An ECS task definition can reference two roles, and both are passed:
Granting PassRole on only the execution role is a common half-fix: RegisterTaskDefinition then fails on the task role instead, with an almost identical message.
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": [
"arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"arn:aws:iam::123456789012:role/app-task-role"
],
"Condition": {
"StringEquals": { "iam:PassedToService": "ecs-tasks.amazonaws.com" }
}
}In Terraform
The identity running terraform apply needs PassRole for every role any resource attaches:
A pipeline role that can create everything but cannot pass roles fails at exactly these lines, which is why deployment roles usually need a PassRole statement scoped to a path covering the roles the stack creates.
resource "aws_instance" "app" {
iam_instance_profile = aws_iam_instance_profile.app.name # needs PassRole
}
resource "aws_lambda_function" "api" {
role = aws_iam_role.lambda.arn # needs PassRole
}A checklist
Frequently Asked Questions
Why is PassRole a separate permission from creating the resource?
Because handing a role to a service grants that service the role's permissions, so without a separate check anyone who could create a Lambda or an EC2 instance could grant themselves whatever that role holds. Attaching an administrator role to a function you control and invoking it is a complete escalation. Splitting the two means the ability to create resources does not imply the ability to choose what permissions those resources run with.
Why should I never use Resource: "*" on PassRole?
Because it lets the holder attach any role in the account to a resource they control. Combined with permission to create a Lambda function or launch an EC2 instance, that is equivalent to granting every permission in the account, via a route that does not look like an admin grant in a policy review. Always list specific role ARNs, or use a path prefix such as arn:aws:iam::123456789012:role/app/* so the grant is bounded and auditable.
What does the iam:PassedToService condition do?
It restricts which AWS service the role may be passed to. A grant conditioned on ecs-tasks.amazonaws.com allows the role to be attached to an ECS task and not to an EC2 instance or a Lambda function. This matters because a role's permissions can be far more dangerous in one execution context than another, and it prevents a role intended for one narrow purpose being repurposed somewhere its permissions combine differently.
I granted PassRole and it still fails. What else is required?
Two other things. The role's own trust policy must allow the service principal to assume it, so a role without ec2.amazonaws.com in its trust policy cannot be an instance profile no matter what you grant. And for EC2, an instance profile object must exist wrapping the role: the console creates one automatically, while the CLI and Terraform do not, so you must create aws_iam_instance_profile explicitly.
Why does my ECS task definition still fail after I added PassRole?
Probably because a task definition references two roles and you granted PassRole on only one. The execution role is used by the ECS agent to pull images and read secrets, and the task role is assumed by your application. RegisterTaskDefinition checks PassRole for both, so granting it on the execution role alone produces a near-identical error naming the task role instead. List both ARNs in the Resource array.
Reference and practice
Learn the underlying concept
Other AWS errors
Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.
Get notified about new tutorials and features.
• Roadmaps
• Interview Prep
• Certifications
• Company
© 2026 DevOpsLesson. All rights reserved.
Need to practice this scenario?
Simulate this error condition and practice recovery commands safely in our in-browser terminal.