- Newest
- Most votes
- Most comments
The fact that STS succeeds while SES returns InvalidClientTokenId suggests that your credentials are valid, but the request signature generated by the SDK is being rejected by the SES endpoint. This is usually not a permission issue (which would return AccessDenied), but a communication/integrity issue.
1. Synchronize System Time (Most Likely Cause)
AWS Signature Version 4 (SigV4) allows a maximum of 5 minutes of "clock skew." If your EC2 instance's time differs from the AWS atomic clock, STS might sometimes pass (depending on the endpoint), but SES is notoriously strict and will reject the request as "invalid."
Run the following on your Ubuntu 22.04 instance:
sudo apt-get update sudo apt-get install ntp -y sudo service ntp restart # Check if the time matches UTC exactly date -u
2. Rotate Credentials (Special Character Issues)
Sometimes, AWS Secret Keys contain special characters (like /, +, or =) that Mautic or specific PHP environments may not escape correctly when constructing the API call, leading to a signature mismatch.
- Action: Generate a new Access Key pair for the
MauticSESuser. If the new Secret Key contains a/or+, delete it and generate another one until you get a "cleaner" alphanumeric string.
3. Check for IAM Boundaries or SCPs
If you are in an AWS Organization, check if there is a Service Control Policy (SCP) or an IAM Permission Boundary attached to the user.
- An SCP can explicitly allow STS actions but restrict SES actions to specific regions or conditions.
- Even if your Inline Policy is
Resource: "*", an SCP acts as a "guardrail" that overrides it.
4. Hardcoded Environment Variables
Since you are using Mautic on EC2, ensure there are no conflicting credentials in:
/etc/environment.envfiles within the Mautic directory- Instance Metadata (IAM Roles) If an IAM Role is attached to the EC2 instance, Mautic might be attempting to use those temporary credentials instead of the ones you provided in the config, leading to a token mismatch.
Based on the error pattern you're describing where STS succeeds but SES fails, this points to an authorization issue specific to Amazon SES rather than a general credential problem.
The most common cause is that the IAM user or role has valid AWS credentials (which is why STS works) but lacks the specific permissions needed to call the SES API. You need to verify that the IAM policy attached to your credentials explicitly grants the ses:SendRawEmail permission (or ses:SendEmail depending on your implementation).
Additionally, if you're seeing "Email address is not verified" errors, ensure that:
- Your sending email addresses or domains are verified in the SES console for the specific region you're using
- If your SES account is still in the sandbox environment, all recipient email addresses must also be verified (except for SES mailbox simulator addresses)
Another potential issue is that the IAM policy might have resource-level restrictions. The policy should allow actions on the specific identity ARNs you're trying to send from.
Since you've tested multiple regions and all fail the same way, I'd recommend:
- Double-check that the IAM user/role has an explicit policy granting SES permissions (not just assumed through other means)
- Verify your identities are confirmed in the exact region your application is targeting
- Confirm your account is out of the SES sandbox if you're sending to non-verified recipients
If all permissions appear correct and identities are verified, this may indeed require AWS Support to investigate potential account-level restrictions or backend service issues.
Sources
Amazon SES SMTP issues - Amazon Simple Email Service
ubuntu@ip-172-31-38-251:/var/www/html$ php /tmp/test-simple.php Testing basic AWS credentials... Access Key: Verified Key Goes Here
✓ Credentials work! User ARN: arn:aws:iam::384406354787:user/MauticSES ubuntu@ip-172-31-38-251:/var/www/html$ ^C ubuntu@ip-172-31-38-251:/var/www/html$ sudo nano /tmp/ses-debug.php ubuntu@ip-172-31-38-251:/var/www/html$ php /tmp/ses-debug.php === SES Debug Test === Access Key: AKIAQVVV... Region: us-east-1
Attempting SES GetSendQuota... ✗ FAILED Error: Error executing "GetSendQuota" on "https://email.us-east-1.amazonaws.com/"; AWS HTTP error: InvalidClientTokenId (client): The security token included in the request is invalid. Code: 0 Type: Aws\Ses\Exception\SesException ubuntu@ip-172-31-38-251:/var/www/html$ ^C ubuntu@ip-172-31-38-251:/var/www/html$ sudo nano /tmp/test-ses-sigv4.php ubuntu@ip-172-31-38-251:/var/www/html$ php /tmp/test-ses-sigv4.php === Testing SES with explicit Signature V4 === Testing GetSendQuota with forced Signature V4... ✗ Still failed: Error executing "GetSendQuota" on "https://email.us-east-1.amazonaws.com/"; AWS HTTP error: InvalidClientTokenId (client): The security token included in the request is invalid.
Security Policy for Group
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ses:SendEmail", "ses:SendRawEmail", "ses:GetSendQuota", "ses:GetSendStatistics", "ses:GetAccountSendingEnabled" ], "Resource": "*" } ] }
Relevant content
- asked a year ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated 6 months ago
