Access Denied while sending email from AWS SES in Lambda function
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
An AccessDenied error from SES inside Lambda usually means one of three things: the Lambda execution role is missing SES permissions, the SES identity is not allowed in that region, or the account is still constrained by SES sandbox rules. The fix becomes much easier once you separate IAM permission failures from SES identity and account-state problems.
Start With the Lambda Execution Role
The Lambda function needs permission to call SES. For a basic send operation, the role usually needs ses:SendEmail or ses:SendRawEmail.
A minimal IAM policy looks like this:
Attach that policy to the Lambda execution role, not to your personal user account. A common mistake is testing with broad permissions in the console and then forgetting that Lambda runs under a different role.
Make Sure the SES Client Uses the Right Region
SES identities and permissions are region-specific in common setups. If the Lambda function creates an SES client in a different region from the verified sender, the call can fail even when the IAM policy looks correct.
A clean boto3 example:
Make the region explicit so the code and the SES setup are clearly aligned.
Check the Sender Identity
SES may deny the send because the Source address or domain is not verified in the region you are using. That is not the same problem as missing IAM permissions, but it often appears during the same debugging session.
If you send from [email protected], verify either:
- that exact email address
- or the domain that covers it
If the identity is not verified, SES rejects the message even when Lambda is allowed to call the API.
Sandbox Restrictions Still Matter
In SES sandbox mode, you can usually send only to verified recipients. That often surprises people because the error shows up during a permission-related workflow, but the root cause is actually account state rather than IAM.
So a good debugging checklist is:
- does the Lambda role have SES send permissions
- is the sender verified in the same SES region
- is the recipient allowed under current SES sandbox rules
You need all three to be true.
Logging the Failure Properly
Log the exact AWS error message from the exception rather than only printing "send failed." That makes the difference between IAM, identity, and sandbox issues visible:
That output often tells you directly whether you are dealing with AccessDenied, a verification problem, or sandbox limitations.
Common Pitfalls
The most common mistake is updating the wrong IAM principal. The Lambda execution role needs permission, not just the developer account.
Another issue is region mismatch. SES setup in one region does not automatically make another region work.
Teams also verify the sender but forget that sandbox mode can still block unverified recipients. That can look like a mysterious policy problem until you check the account state.
Summary
- Check the Lambda execution role first for
ses:SendEmailorses:SendRawEmail. - Use the SES client in the same region where your sender identity is verified.
- Verify the sender address or domain before sending.
- Remember that SES sandbox mode can still restrict recipients.
- Log the exact AWS error code and message so IAM and SES configuration issues do not get mixed together.
Related reading
- Access key ID and Secret Access Key for AWS Educate account
- Access POST Request body from Custom Authorizer Lambda Function
- access postgres in kubernetes from an application outside the cluster
- AccessDenied for ListObjects for S3 bucket when permissions are s3
- Access denied; you need at least one of the SUPER privileges for this DEFINER operation
- ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN
- AccessDenied Not authorized to perform stsAssumeRoleWithWebIdentity
- AccessDeniedException User is not authorized to perform lambdaInvokeFunction

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.