InvalidParameterValueException: The role defined for the function cannot be assumed by Lambda.

Short answer

The role exists and its permissions may be perfect — but its trust policy does not allow lambda.amazonaws.com to assume it. That is a different document from the permissions policy, and it is the one people check second.

What it means

An IAM role has two policies that do completely different jobs, and this error is what happens when the wrong one has been attended to. The permissions policy says what the role may do — read this bucket, write that table. The trust policy says who may become the role in the first place. Lambda is refusing here because the trust policy does not list it.

That distinction is the whole diagnosis, and it is easy to miss because the permissions policy is the one people think about. A role can grant complete access to every service you use and still be unusable by Lambda, because the question being asked is not "what can this role do" but "may lambda.amazonaws.com assume it". A role created for EC2, for ECS, or for a human to switch into has a perfectly valid trust policy that simply names a different principal.

The second cause is timing, and it is worth recognising because it looks identical and needs no fix at all. IAM is eventually consistent. A role created and immediately handed to CreateFunction can genuinely not exist yet from Lambda's point of view, and the same deployment succeeds seconds later with nothing changed. If your CI fails on a fresh stack and passes on re-run, that is this — not a policy error, and adding permissions to chase it will not help.

Nothing about this reaches CloudWatch Logs, because there is no function yet to write any. It lives entirely in the response to the API call: a sam deploy tail, a CloudFormation stack event, or the CLI output. That is also why it is worth getting the deployment tool to declare the role alongside the function — CloudFormation and SAM order the creation, wire the ARN, and remove both the trust-policy mistake and the propagation race without anyone having to remember either.

Where you'll see it

Deployment output

Not in CloudWatch
$ aws lambda create-function \
--function-name orders-fn \
--runtime nodejs22.x \
--handler index.handler \
--role arn:aws:iam::111122223333:role/orders-fn-role \
--zip-file fileb://function.zip
An error occurred (InvalidParameterValueException) when calling the CreateFunction
operation: The role defined for the function cannot be assumed by Lambda.

This failure happens before the function runs, so nothing about it reaches CloudWatch Logs — there is no invocation, and no log group entry to find. Once the deployment succeeds and the function starts running, the rest of this index covers what you will see there.

Causes, most likely first

1

The role's trust policy does not name lambda.amazonaws.com

How to confirm

Read the role's trust policy — not its permissions policy, which is the one people check first and is almost never the problem here. The trust policy must have a statement allowing sts:AssumeRole for the lambda.amazonaws.com service principal. A role created for EC2, ECS, or a human user has a different principal and cannot be handed to Lambda.

2

The role was created moments ago and has not propagated

How to confirm

Check whether the deployment creates the role and the function in the same run, and whether retrying immediately succeeds. IAM is eventually consistent across regions, so a role can exist in the API and still be unusable for a few seconds — which makes this fail on a fresh stack and pass on a retry with no changes.

3

The role ARN points at a different account

How to confirm

Compare the account number in the role ARN against the account you are deploying into. A role ARN copied from another environment refers to a role Lambda in this account cannot assume regardless of either role's policies.

4

A permissions boundary or SCP blocks the assumption

How to confirm

Check for a permissions boundary on the role and for service control policies in the organization. Both can prevent the service principal assuming the role even when the trust policy is written correctly, and neither shows up in the trust policy itself.

5

The role name is right but the path is wrong

How to confirm

Compare the full ARN, including any IAM path segment. A role created at /service-role/ has an ARN of arn:aws:iam::111122223333:role/service-role/name, and referencing it without the path resolves to a role that does not exist — which reports as an assumption failure rather than as not-found.

Fixes

Fix 1

Write a trust policy that names the Lambda service principal

This is the fix in almost every case. The trust policy is a separate document from the permissions policy, and it is the one that says who may become this role.

json{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "lambda.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}
Fix 2

Let the deployment tool create the role, so ordering is handled for you

In CloudFormation or SAM, declaring the role alongside the function makes the dependency explicit and removes both the trust-policy mistake and the propagation race in one step.

yamlResources:
  OrdersFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal: { Service: lambda.amazonaws.com }
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  OrdersFunction:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt OrdersFunctionRole.Arn
Fix 3

Read the trust policy back before changing anything else

One command tells you whether this is a policy problem or a timing problem, and they have completely different fixes.

bashaws iam get-role --role-name orders-fn-role \
  --query 'Role.{Arn:Arn,Trust:AssumeRolePolicyDocument}'
Fix 4

Retry once if the role was just created

Where the trust policy is provably correct and the role is seconds old, this is IAM propagation and it resolves on its own. A short retry in the deployment script is the pragmatic answer; Terraform users often reach for a depends_on plus a brief delay for the same reason.

Also seen as

The same underlying failure, worded differently by a different runtime, SDK version, or logging layer. All of these land here — there is no separate page for each phrasing.

The role defined for the function cannot be assumed by LambdaAn error occurred (InvalidParameterValueException) when calling the CreateFunction operationlambda role cannot be assumedlambda trust policy errorsts:AssumeRole lambda.amazonaws.com

Errors that show up alongside this one, or that people mistake for it.

References

This one happens before there are any logs.

LogStitch reads CloudWatch, and a deployment that fails never writes to it — so this is not an error it can find for you. Once the function deploys and starts running, the free web stitcher groups its invocations in your browser, and the Mac app does the same across every function in your account.