@Mail Domain Check

Firebase Authentication - email delivery - action codes

Firebase Auth verification email not received: trace the request before retrying

A resolved sendEmailVerification() or sendPasswordResetEmail() call does not prove inbox visibility. A generated Admin SDK action link does not send a message at all. Trace the exact project, user, quota, sending path, receiver evidence, and action-code result separately.

Start with six separate proofs

1. Application call
Prove which client SDK call ran, or whether a server generated only an action link. Preserve the bounded result, project, tenant, UTC time, and random correlation ID.
2. User and environment
Prove the intended Firebase project, production environment, current user, provider state, and whether emailVerified is already true.
3. Firebase limit
Check the current operation-specific email quota and abuse controls. Verification, password-reset, and email-link sign-in messages have separate limits.
4. Sending path
Separate Firebase's template-based email path from an Admin SDK link that your own provider must send, or an Identity Platform custom SMTP path.
5. Receiver visibility
A successful API call is not an SMTP receipt. Provider acceptance is not inbox placement. Check the strongest event or mailbox evidence the selected path exposes.
6. Action-code use
An arrived message can still fail because its oobCode is expired, invalid, already used, or opened by the wrong handler.

Build the first-action plan locally from bounded states. No recipient, message, action link, code, token, or Firebase credential is entered.

Never paste a recipient address, message, oobCode, complete action link, password, ID token, refresh token, custom token, service-account JSON or private key, SMTP password, provider API key, webhook secret, seed phrase, private key, or wallet signature into a public diagnostic or incident post.

Prove what the application actually did

Start from the exact operation and runtime. Client SDK calls and Admin SDK link generation have different outcomes.

  • sendEmailVerification(user, actionCodeSettings) asks Firebase Authentication to send a verification message for the signed-in user. A fulfilled Promise is application evidence, not a receiver receipt.
  • sendPasswordResetEmail(auth, email, actionCodeSettings) starts the password-reset email flow. Record only the bounded error code and correlation data outside the private system.
  • generateEmailVerificationLink(), generatePasswordResetLink(), and generateSignInWithEmailLink() in the Admin SDK generate links. The application must insert the link into a template and send it through its own provider.
  • Updating a user record or logging "email sent" without calling a sending API is not delivery evidence.

Record the SDK and version, method, Firebase project ID, tenant when applicable, UTC time, platform, random correlation ID, bounded error code, and whether the call ran in a client, trusted server, test environment, or production. Keep the address and action link private.

Check project, tenant, user, and provider state

  1. Confirm that the application initialized the intended Firebase project and Auth instance. A valid call against a test project does not create evidence in production.
  2. For multi-tenant Identity Platform, prove the intended tenant configuration before comparing templates, domains, SMTP, limits, or users.
  3. For verification, prove that the current user exists in Firebase Authentication and has a usable email attribute. A Firestore document is not a Firebase Auth user record.
  4. Reload the user before trusting emailVerified. A stale client object can show the pre-verification state after a code was applied elsewhere.
  5. For password reset or email-link sign-in, confirm that the intended provider and flow are enabled without publishing whether a particular person has an account.

Do not weaken email-enumeration protection to make debugging easier. Use private project evidence and bounded errors instead of exposing account existence to a public client.

Check the current email operation limit

Firebase publishes different daily limits for address-verification, password-reset, address-change, and email-link sign-in messages, with plan-dependent values and abuse protections that can change. Read the current limits for the affected project and operation instead of copying an old number from a forum.

  • Classify the exact message type before checking quota; unused verification capacity does not prove password-reset capacity.
  • Preserve the first bounded quota or abuse error. Repeated retries can consume more capacity and erase the timing of the original incident.
  • If a higher legitimate threshold is required, change the plan or request the documented adjustment. Do not rotate projects or recipients to evade a limit.

Identify who is responsible for sending

Firebase Client SDK user-management emails use project templates and Google's sending path. Template-based emails are sent by Google and have limited customizability. The strongest private evidence may therefore stop at the Auth request unless the selected product and configuration expose more.

An Admin SDK generated action link is different: link generation proves only that Firebase created a URL. Your application, queue, template renderer, email provider, SMTP transaction, and receiver are all separate boundaries after that point.

If Firebase Authentication with Identity Platform is configured with custom SMTP, verify the exact tenant or project configuration, From identity, SMTP authentication, quota, suppression, provider event trail, and domain authentication. A custom SMTP test in another project or tenant is not evidence for this flow.

  1. Inspect the correct Authentication email template, language, sender, reply-to, subject, and action URL.
  2. If using a custom domain in the From field or action links, prove its verification and the exact template assignment.
  3. For your own provider, correlate queue ID, provider message ID, ordered events, SMTP response, and actual sending IP.
  4. If no message-level event exists for the default path, mark provider and SMTP delivery as unproven. Do not invent a delivery event from the SDK Promise.

After sending evidence, inspect the receiver

Classify scope before changing configuration: one mailbox, one receiving domain, one template, one project or tenant, or every authentication message. Check spam, junk, quarantine, security gateways, category tabs, forwarding, aliases, rules, groups, storage, and mailbox trace data.

For a custom provider, a provider "delivered" event generally means the recipient's mail server accepted the message, not that a person saw it. Preserve the exact provider semantics and SMTP diagnostic. For Firebase's default path, absence from the inbox does not identify which hidden boundary failed.

When a controlled message is available, export its complete original header. Compare trusted receiver time with the application event, then inspect 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 deferral on a custom path, preserve the complete SMTP reply and decode it locally. Temporary 4xx and permanent 5xx outcomes require different retry behavior.

Separate link delivery from link completion

Firebase email action links contain an out-of-band code and a mode such as verifyEmail, resetPassword, or recoverEmail. A message can arrive successfully while the action fails.

  • auth/unauthorized-continue-uri and related ActionCodeSettings errors belong to request configuration, before receiver delivery.
  • auth/expired-action-code and auth/invalid-action-code belong to code use. The code may be old, malformed, or already consumed.
  • A custom handler must route the correct mode and call the matching Firebase API, such as applyActionCode() for email verification.
  • Link scanners and previews can open URLs before the intended user. Compare issuance, gateway, first-request, and application timestamps before declaring transport failure.

Never place a complete action URL or oobCode in a public ticket, analytics event, screenshot, chat, or diagnostic form.

The first ten minutes

  1. Record the exact SDK or Admin method, runtime, UTC time, project, tenant, template, random correlation ID, and bounded result.
  2. Prove the Firebase Auth user and provider state without using a Firestore row as a substitute.
  3. Check the current operation-specific limit and stop uncontrolled retries.
  4. Classify Firebase template sending, Admin SDK link generation plus custom provider, or Identity Platform custom SMTP.
  5. Follow the strongest available event to provider, SMTP, and receiver evidence; mark any hidden boundary as unknown.
  6. If the message arrived, diagnose handler, mode, continue URL, and action-code state separately.

Build a safe incident packet

Application
SDK and version, method, platform, UTC time, project alias, tenant alias, template version, random correlation ID, and bounded error.
Firebase Auth
Environment, provider enabled state, user-state category, refreshed verification state, current operation-limit state, and sending-path category.
Custom delivery
Queue state, provider message ID, ordered event names, bounded SMTP diagnostic, sending IP, and visible From domain.
Receiver
Affected receiving domain and scope, private trace or quarantine evidence, and controlled original header when available.
Action handler
Mode, handler version, authorized-domain result, and expired, invalid, used, or applied state without the URL or code.
Exclusions
No recipient, message, action URL, code, password, token, service-account material, SMTP credential, API secret, or wallet secret.

Inventory every Firebase Auth message path locally, including project, tenant, flow, template, From domain, delivery owner, DKIM identity, provider evidence, action handler, and rollback owner.

Check the visible From domain's public sender controls. Public DNS can confirm SPF, DKIM, DMARC, PTR, and transport-policy publication, but it cannot read Firebase, a provider account, an action code, or a mailbox.

This independent guide is not affiliated with Google or Firebase. Firebase Authentication and the selected email provider are the sources of truth for their private boundaries; the receiving administrator remains the source of truth for private filtering.

Primary references