Access Denied while sending email from AWS SES in Lambda function
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
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.

