Start with the boundary map
- 1. Cognito request
- Record the operation, user pool, app path, region, UTC time, random correlation ID, bounded response, and any
CodeDeliveryDetails. Signup, confirmation resend, invitation, and password recovery have different preconditions. - 2. User and recovery state
- Check the user's status, verified recovery attributes, account-recovery configuration, and intended delivery medium. A request can succeed without selecting the mailbox the operator expected.
- 3. Cognito email mode
- Identify
COGNITO_DEFAULTversusDEVELOPERwith Amazon SES. Default quotas and custom-identity requirements belong to this boundary. - 4. Amazon SES
- For the SES path, prove identity, region, permissions, sandbox or production state, quota, suppression state, and a matching event trail.
- 5. SMTP and receiver
- A provider
Deliveryevent means the receiving server accepted the message. It does not prove inbox placement, visibility, or mailbox control. - 6. Code use
- If the message arrived but the code is invalid or expired, investigate code timing, retries, and account state separately from transport.
Build the first-action plan locally from observed states only. No email address, message, code, token, or credential is entered.
Never paste an AWS access key, secret access key, session token, Cognito app client secret, SECRET_HASH, JWT, verification code, recipient address, message, SES SMTP password, provider API key, webhook secret, seed phrase, private key, or wallet signature into a public diagnostic or incident post.
Prove which Cognito operation ran
Start from the exact API or managed-UI operation. SignUp, ResendConfirmationCode, ForgotPassword, and AdminCreateUser do not share identical eligibility, user-state, or message-template behavior. Preserve the bounded HTTP status, AWS request ID, user-pool region, timestamp, and delivery medium without logging a recipient or secret.
SignUpcan create anUNCONFIRMEDuser and return delivery details, but that response does not prove an SES event or receiver acceptance.ResendConfirmationCodeapplies to an eligible unconfirmed user. A confirmed account needs a different diagnosis.ForgotPasswordrequires an eligible verified recovery attribute selected by the user pool's account-recovery settings.AdminCreateUsernormally creates aFORCE_CHANGE_PASSWORDinvitation flow; suppressed invitations, temporary-password behavior, and message-template settings belong to that path.
For privacy and account-discovery resistance, Cognito can avoid revealing whether a username exists. A generic success response is therefore not evidence that a message was created for a particular person.
Check user state and the selected destination
Read the user privately in the correct user pool and region. Compare UserStatus, the presence of the email attribute, email_verified, enabled aliases, and AccountRecoverySetting. Do not copy the attribute value into an external ticket.
- Confirm that the application is calling the intended user pool and app client in the intended AWS region.
- Classify
UNCONFIRMED,CONFIRMED, andFORCE_CHANGE_PASSWORDbefore choosing signup confirmation, password recovery, or invitation actions. - For
ForgotPassword, prove that a verified attribute is eligible under the current recovery priority. An unverified email can exist without being a usable password-recovery destination. - Compare the masked destination and
DeliveryMediuminCodeDeliveryDetailswith the expected channel without exposing the underlying address.
Identify the Cognito email mode
Read the user pool's EmailSendingAccount. With COGNITO_DEFAULT, Cognito sends through an AWS-managed path with a deliberately small daily quota. AWS documented 50 messages per day at this guide's publication; consult current quotas instead of treating that number as permanent.
With DEVELOPER, the user pool sends through the account's Amazon SES configuration. Verify the exact SourceArn, From identity, configuration set, and supported SES region. A verified identity in a different region does not prove that the configured user-pool path can use it.
- Check CloudTrail and bounded Cognito errors for authorization, identity, quota, template, Lambda trigger, or configuration failures.
- If a custom email-sender Lambda trigger is configured, treat its invocation and encryption/decryption path as a separate application boundary.
- Do not add broad IAM permissions as a diagnostic shortcut. Correct the specific identity, region, sending-authorization, or role relationship named by the evidence.
Trace the Amazon SES boundary
In the SES sandbox, sending is restricted to verified recipients or the mailbox simulator, even when the From identity is verified. Request production access in the relevant region before using the path for real users. Also inspect the current sending quota and rate rather than assuming another region's status applies.
- Verify the exact email address or domain identity used by the Cognito configuration in the same supported SES region.
- Check the account-level and global suppression lists before one controlled retry. Remove a suppression only after the underlying bounce or complaint condition is understood.
- Use a configuration set and event destination to capture
Send,Delivery,Bounce,Complaint,Reject,Rendering Failure, andDeliveryDelayevidence. - Correlate by AWS request ID, SES message ID, event time, template, and bounded destination domain. Do not publish the recipient or message.
A Send event means SES accepted the request for sending. A Delivery event means the recipient's mail server accepted the message. Neither event proves that the user saw it in the inbox.
After receiver acceptance, inspect private filtering
Search the mailbox's own interface, spam or junk, quarantine, security gateways, category tabs, aliases, forwarding, groups, rules, and storage. If only one receiving domain is affected, involve its mail administrator with the SES message ID, acceptance time, visible From domain, and bounded SMTP evidence.
When a controlled message can be found, export its complete original header. Compare trusted receiver timestamps with the SES event, then read the final receiver's Authentication-Results, visible From, DKIM d=, SPF identity, DMARC alignment, and newest trusted Received fields. Analyze the header locally without uploading it.
For a bounce or delay, preserve the complete SMTP response and decode it locally. Separate temporary 4xx deferrals from permanent 5xx failures before changing DNS or retry behavior.
The first ten minutes
- Record operation, UTC time, user-pool region, app path, scope, AWS request ID, and bounded response.
- Classify user status, verified recovery attribute, recovery priority, delivery medium, and masked destination.
- Identify
COGNITO_DEFAULT,DEVELOPER, or a custom sender trigger and stop at the first missing proof. - For SES, check region, identity, sandbox state, quota, suppression, configuration-set events, and the exact message ID.
- After receiver acceptance, check private filtering and obtain a trusted original header when possible.
- Name one owner, one corrective action, and the evidence required before one controlled retry.
Build a safe incident packet
- Application
- Operation, app path, UTC time, random correlation ID, scope, template version, and bounded client or server error.
- Cognito
- User-pool region, request ID, user status, delivery medium, masked destination, recovery setting, and email mode.
- Amazon SES
- Region, identity ARN without credentials, sandbox or production state, quota state, SES message ID, ordered event names, and bounded failure reason.
- Receiver
- Affected domain and scope, SMTP diagnostic, quarantine or rule evidence, and a controlled original header when available.
- Exclusions
- No recipient, message, verification code, token, password, access key, secret, session credential, SMTP credential, API key, or wallet secret.
- Next action
- The first unproven boundary, its owner, one corrective action, and the condition for one controlled retry.
Inventory the Cognito sending path locally so user pool, region, email mode, From domain, SES identity, DKIM identity, Return-Path, event destination, and incident owner remain visible.
Check the visible From domain's public sender controls. Public DNS can confirm published SPF, DKIM, DMARC, PTR, and transport-policy evidence, but it cannot read Cognito, SES, or a mailbox.
This independent guide is not affiliated with Amazon Web Services. Cognito, CloudTrail, and Amazon SES are the sources of truth for their private boundaries; the receiving administrator remains the source of truth for private filtering.
Primary references
- AWS: Email settings for Amazon Cognito user pools
- AWS re:Post: Troubleshoot ForgotPassword code delivery
- AWS: User-pool password recovery
- AWS: Amazon Cognito quotas
- AWS: Cognito message and SES identity customization
- AWS: Move an Amazon SES account out of the sandbox
- AWS: Monitor Amazon SES with event publishing
- AWS: Amazon SES suppression lists
- RFC 5321: Simple Mail Transfer Protocol