User: arn:aws:iam::123456789012:user/developer is not authorized to perform: lambda:InvokeFunction on resource: my-function

Short answer

Whoever is calling the function may not call it. This is the caller's permissions, not the function's execution role — the two are frequently confused, and adding permissions to the execution role does nothing for this.

What it means

Every Lambda function has two entirely separate permission questions, and this error is about the one people check second. The execution role governs what the function may do once it runs — read this table, write that bucket. Invoke permission governs who may run it at all. They are different policies, on different principals, and adding permissions to the execution role has no effect whatsoever on this error.

The User: field settles which you are looking at. It names the principal that was refused, and for this error it is the caller — a developer's IAM user, a CI role, an API Gateway, another function. If that ARN is not your function's execution role, and it usually is not, the problem is on the calling side.

There is a second axis that catches cross-account and service integrations. Lambda invoke can be granted from the identity side, the resource side, or both, and which one is required depends on the caller. Within one account an identity policy is enough. Across accounts, and for AWS services like S3, SNS and EventBridge, the function needs a resource-based policy of its own — that is what aws lambda add-permission writes, and it is the step most often missing when a service integration does not fire.

Two details produce errors that look like a correct policy being ignored. Qualifiers: an alias or version is part of the resource ARN, so a policy naming function:orders-fn does not cover function:orders-fn:PROD, and traffic routed through an alias is refused by a policy that appears to grant it. Function URLs: those authorize lambda:InvokeFunctionUrl, a distinct action, so a policy granting lambda:InvokeFunction is simply about something else.

As with any IAM denial, the clause at the end of the message decides the fix. "Because no identity-based policy allows" means adding the permission works. Anything naming an explicit deny, a permissions boundary, or a service control policy means an allow cannot override it, and the change belongs at that level instead.

Where you'll see it

Deployment output

Not in CloudWatch
$ aws lambda invoke --function-name my-function /tmp/out.json
An error occurred (AccessDeniedException) when calling the Invoke operation:
User: arn:aws:iam::123456789012:user/developer is not authorized to perform:
lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:123456789012:function:my-function
because no identity-based policy allows the lambda:InvokeFunction action

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 caller's identity policy does not allow lambda:InvokeFunction

How to confirm

Read the principal in the User: field and check that identity's policies. The principal is whoever is invoking — a developer, a CI role, another function, an API Gateway — and it is almost never the function's own execution role, which governs what the function does rather than who may call it.

2

A resource-based policy is required and absent

How to confirm

Check the function's resource policy with get-policy. Cross-account callers and AWS services like S3, SNS and EventBridge need a statement on the function granting them invoke — an identity policy alone is not enough across an account boundary.

3

The qualifier does not match what the policy grants

How to confirm

Compare the ARN in the message with the resource in the policy. Permission on function:my-function does not automatically cover function:my-function:PROD; an alias or version qualifier is part of the resource, and a policy written for the unqualified function does not extend to it.

4

A Function URL is being called and needs its own action

How to confirm

Check whether the invocation goes through a Function URL. Those authorize lambda:InvokeFunctionUrl, which is a distinct action — granting lambda:InvokeFunction does not cover it.

5

An explicit deny is overriding the allow

How to confirm

Read the reason at the end of the message. "No identity-based policy allows" means nothing granted it and adding a grant will work; wording that mentions an explicit deny, a permissions boundary, or an SCP means something is actively refusing and a new allow will change nothing.

Fixes

Fix 1

Grant the caller the action, on the exact resource in the message

Copy the ARN out of the error rather than reconstructing it — including any alias or version qualifier, which is part of the resource and easy to omit.

yaml- Effect: Allow
  Action: lambda:InvokeFunction
  Resource:
    - !GetAtt OrdersFunction.Arn
    # Aliases and versions are separate resources.
    - !Sub "${OrdersFunction.Arn}:*"
Fix 2

Add a resource-based policy for a service or another account

An AWS service invoking your function needs a statement on the function itself. SourceArn keeps the grant narrow, so an EventBridge rule can invoke it and an arbitrary caller in the same service cannot.

bashaws lambda add-permission \
  --function-name orders-fn \
  --statement-id eventbridge-daily \
  --action lambda:InvokeFunction \
  --principal events.amazonaws.com \
  --source-arn arn:aws:events:us-east-1:111122223333:rule/daily-reconcile
Fix 3

Read the function's resource policy before assuming it is the identity

Half of these are the function's policy rather than the caller's, and one command tells you which half you are in.

bashaws lambda get-policy --function-name orders-fn \
  --query 'Policy' --output text | python3 -m json.tool
Fix 4

Use InvokeFunctionUrl for Function URL callers

Function URLs authorize a different action. Granting the wrong one produces this error while the policy looks entirely correct.

yaml- Effect: Allow
  Action: lambda:InvokeFunctionUrl
  Resource: !GetAtt OrdersFunction.Arn
  Condition:
    StringEquals:
      lambda:FunctionUrlAuthType: AWS_IAM

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.

is not authorized to perform: lambda:InvokeFunctionAccessDeniedException when calling the Invoke operationUser is not authorized to perform lambda:InvokeFunctionUrllambda invokefunction access deniedlambda cannot invoke function permission

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.