Start with seven separate proofs
- 1. Flow
- Classify email verification, reset password, magic link, email OTP, organization invitation, or infrastructure email service. They use different callbacks and terminal states.
- 2. Auth state
- Prove the user category, email verification requirement, sign-up policy, token lifetime, and request timestamp without exposing the address or token.
- 3. Callback execution
- Confirm that
sendVerificationEmail,sendResetPassword,sendMagicLink,sendVerificationOTP, or a managed email-service call actually ran. - 4. Durable handoff
- Do not treat a fire-and-forget callback as delivery. Preserve a provider message ID, queued job ID, or explicit failure class.
- 5. Provider event
- Follow suppressed, failed, delayed, bounced, sent, accepted, or delivered events using the provider's documented semantics.
- 6. Receiver visibility
- Check spam, quarantine, security gateways, forwarding, aliases, rules, storage, and a trusted original header when a controlled message is available.
- 7. Token use
- If the message arrived, separate expiration, duplicate use, scanner prefetch, wrong callback URL, and successful verification from mail delivery.
Build the first-action plan locally. No recipient, message, verification URL, reset link, OTP, token, cookie, API key, SMTP password, provider secret, database row, or wallet secret is entered.
Never paste a verification URL, reset URL, OTP, bearer token, session cookie, provider API key, SMTP credential, database row containing a user address, seed phrase, private key, or wallet signature into a public issue or diagnostic.
Identify the Better Auth flow first
Better Auth supports email and password authentication plus plugins such as magic link and email OTP. A missing reset email is not the same incident as a missing sign-up verification email or an OTP that arrived but failed verification.
- Email verification uses the
emailVerificationconfiguration and itssendVerificationEmailcallback. IfsendOnSignUpis enabled, prove that the sign-up path reached this callback. - Password reset uses
emailAndPassword.sendResetPassword. A reset-token URL can be created without proving that the message was sent or accepted. - Magic link uses the magic-link plugin and its
sendMagicLinkfunction. - Email OTP uses the email-OTP plugin for sign-in, verification, or password reset with one-time codes.
- Better Auth Infrastructure email service is a managed provider path. Its API result and message ID must still be followed to provider and receiver evidence.
Record the flow name, deployment environment, Better Auth version, route, UTC time, random correlation ID, bounded response, and callback name. Keep the address, token, OTP, full URL, cookies, and provider secret private.
Check auth state before the mail path
- Confirm that email and password auth is enabled when the flow depends on it. If sign-up is disabled or an account already exists, the expected email can change.
- Classify whether email verification is required before session creation, optional after sign-up, or handled by a plugin.
- For password resets, capture whether the user lookup produced the neutral anti-enumeration response, a private known-user reset, or an account-state block.
- For OTP or magic link, record the purpose, token lifetime, resend limit, and whether a previous token was invalidated.
- For invitations or organizations, prove the invitation object, inviter authority, recipient role, and accepted or expired state separately from email transport.
Do not weaken enumeration protection to debug a public report. Use private categories and a controlled test account owned by the operator.
Prove the callback or provider call ran
The most common false success is an authentication endpoint that returns before the mail function is awaited, committed, or observable. A callback that calls void sendEmail(...), a background task, or a queue without durable state can make the UI say "sent" while the provider never accepted the message.
- Wrap the callback with a correlation ID and bounded status such as
queued,provider_accepted,provider_failed, orcallback_threw. - Persist the attempt after the auth state is valid and before the UI claims that a message was sent.
- Keep provider message ID, template ID, stream, From identity, and response code. Do not log the URL, token, OTP, recipient, or full provider payload.
- If the app uses a managed email service, preserve its returned message ID and error class; do not stop at an HTTP 200 or a promise resolution.
Follow the provider event, not the framework label
Once Better Auth or the email-service wrapper hands off the message, the email provider owns the next boundary. Read the provider event trail before changing DNS.
- Confirm the verified From domain or Sender identity that actually sent the message.
- Check account state, plan or quota, suppression list, template rendering, region, stream, and webhook delivery.
- Preserve the first suppression, failure, deferral, bounce, or SMTP reply. Decode the SMTP reply locally before retrying.
- If the provider reports delivered, retain the provider's definition. Usually it means a receiving mail system accepted the message, not that the user saw it.
Check the actual visible From domain and Return-Path used by the provider. Public DNS for the wrong app domain cannot explain a missing Better Auth email.
After provider acceptance, inspect the receiver
Scope the incident: one mailbox, one receiving domain, one template, one provider stream, one deployment, or every transactional email. Then inspect spam, junk, quarantine, security gateways, aliases, forwarding, rules, storage, and mailbox trace data.
For a controlled message that arrived, export the complete original header and analyze it locally. Compare trusted receiver timestamps, SPF, DKIM, DMARC alignment, visible From, Return-Path, DKIM d=, and the newest trusted Received fields.
Separate token use from mail delivery
If the user can find the email but the link or code fails, stop treating the problem as deliverability.
- Correlate token issuance, provider acceptance, receiver acceptance, first URL request, app callback result, and final verification or reset state.
- Detect link-preview or security-scanner prefetch without logging the secret URL.
- Keep expiration, duplicate use, replaced token, wrong callback host, wrong environment, and successful completion as separate outcomes.
- Do not extend token lifetime or make tokens reusable as a delivery workaround.
The first ten minutes
- Name the exact Better Auth flow and callback.
- Record auth-state categories and a random correlation ID.
- Prove callback execution, durable attempt state, and provider message ID or bounded failure.
- Follow the provider event trail to suppression, failure, delay, bounce, or receiver acceptance.
- Check private receiver evidence only after provider acceptance.
- If the message arrived, debug token or OTP use as a separate incident.
Build a safe incident packet
- Application
- Flow, route, environment, Better Auth version, UTC time, correlation ID, and bounded response.
- Auth state
- User-state category, verification requirement, token purpose, token lifetime, and resend or invalidation policy.
- Callback
- Callback name, attempt state, provider name, template or stream alias, message ID, and bounded error class.
- Provider
- Ordered event names, SMTP reply category, sending IP, visible From domain, and Return-Path domain.
- Receiver
- Affected receiving domain and scope, quarantine or trace result, and controlled original-header evidence.
- Completion
- Expired, invalid, prefetched, duplicate, wrong host, wrong environment, or accepted state without the secret.
Inventory each Better Auth email path locally, including flow, provider, visible From domain, DKIM identity, Return-Path, owner, provider event, receiver evidence, and rollback owner.
Check the public sender controls only after you know the visible From domain. DNS cannot read Better Auth callbacks, provider logs, receiver quarantine, OTP state, or a private database.
This independent guide is not affiliated with Better Auth. Better Auth, the configured email provider, and the receiving administrator remain the sources of truth for their private systems.