Zodiac Tech CRM Docs

Email or OTP not received

Fix missing transactional emails, email OTP codes and phone OTP/SMS codes — SMTP configuration, login-method switches, rate limits and Firebase.

admin super-admin developer Medium ⏱ 15 min Updated 2026-10-05

Email or OTP not received

"Send code" does nothing, or an email the CRM claims to have sent never arrives. This covers all three channels: transactional email (invites, digests, sequences), email OTP for mobile sign-in, and phone OTP/SMS (Firebase or the workspace's SMS provider). The first question is always the same: did the CRM hand the message to a real sender, or to a mailbox that pretends to send?

Who this is for: workspace admins and super admins handling delivery complaints.

Problem

An expected email or one-time code does not arrive — or arrives so late it has expired. The app's screen may look successful ("code sent") while nothing was delivered.

What you see

Symptom Where
Mobile login errors: otp_send_failed, RATE_LIMITED (with retry_after), otp_unavailable Android app
"This login method is not enabled" Android app login screen
A message about incomplete Firebase configuration Android app when phone OTP goes through Firebase
Test email from the CRM never arrives Admin → Email settings
Digests/sequences silent for the whole workspace Admin inboxes

Likely causes

  • Mail is configured to a non-delivering mailer. If global mail is set to log or array, the CRM "sends" perfectly and nothing leaves the server. This is the most common cause of "the CRM says it emailed me".
  • SMTP credentials wrong or blocked (host, port, encryption, username/password, from-address rejected by the provider).
  • Wrong switch, not wrong pipe: email OTP (email_otp) is on by default, phone OTP (phone_otp) is off by default — a workspace may simply not have enabled the method the user is trying.
  • Rate limits are doing their job: OTP issuance is capped (3 codes per identifier, 10 per IP, per 10-minute window) and verification is capped at 5 attempts; the code itself expires (~10 minutes by default).
  • Phone OTP needs a working channel: either the workspace's Firebase project (verified server-side) or a configured SMS provider (Twilio/Plivo/custom) — neither means no code.
  • Spam filtering, greylisting, or a provider-side block on the recipient.
  • Slow queues: digest/sequence mail is queued; a stalled worker delays everything.

Quick fix

  1. Check spam/junk and search all mailboxes — give it two minutes, then resend once. Do not hammer resend: the rate limit will then lock you out for the rest of the window.
  2. Admin sends a test email from Admin → Email settings (/admin/email-settings-page, "Send test email"). If the test does not arrive, it is a configuration problem, not a user problem.
  3. Try OTP on a different channel or method to isolate (email OTP vs phone OTP vs password).

Step-by-step fix

  1. Prove the pipe with the test email (above). Then check the sender configuration:
    • Global mail: Super Admin → Settings → Script Settings (/super-admin/settings/script-settings) — mailer (smtp | sendmail | log | array), host, port, encryption, username, password, from address/name. If the mailer is log or array, fix that first.
    • Workspace-specific sends (like email OTP) use the tenant's SMTP when the tenant has set smtp.host; otherwise they fall back to the platform mailer. Verify the tenant's SMTP under the workspace's email settings.
  2. Check the method switches. Super Admin → Settings → Mobile App Login (/super-admin/settings/mobile-app-login) and the tenant override Admin → Mobile login settings (/admin/mobile-login-settings-page). Defaults: email+password and email OTP enabled, phone OTP disabled, Firebase disabled. Enable what the workspace actually uses.
  3. Phone OTP specifically:
    • With Firebase enabled, the app verifies with Google and sends the Firebase id_token to the server — an "incomplete configuration" message means the Firebase details are missing or wrong (the same Firebase project as Push notifications (FCM)).
    • With Firebase off, the code goes through the workspace's SMS provider (Twilio, Plivo or custom). Check the provider credentials and balance.
  4. Respect the rate limits. RATE_LIMITED returns retry_after — wait that many seconds rather than retrying. The issuance window is 10 minutes; 3 starts per identifier and 10 per IP per window.
  5. Queued email not flowing at all? If digests, sequences and invites are collectively late, the queue is the problem, not email — see the queue runbook in Incident response. Digests run hourly, email sequences every 15 minutes, mailbox checks every 5 minutes.

Admin fix

  • Correct the mailer/credentials (global or tenant) and re-send the test until it lands.
  • Enable the login methods the workspace needs, and note that phone OTP requires Firebase or an SMS provider before it can deliver anything.
  • For a user who genuinely received nothing after a resend: check the CRM side first (test email), then the user side (spam, mailbox full, typos).

Developer fix

  • Email OTP is sent synchronously (Mail::to(...)) during the request; a failure surfaces as otp_send_failed and logs "Mobile OTP email failed" in storage/logs/laravel.log.
  • OTP codes are stored HMAC-SHA256-hashed with a random salt; max 5 verify attempts; issuance rate-limited per identifier and per IP. Code length 6, TTL ~10 minutes (configurable in the mobile auth settings).
  • Firebase phone OTP is verified server-side (Google getAccountInfo on the id_token); SMS fallback uses the tenant's messaging provider.
  • Phone lookup strips separators and matches the last 10 digits — a number outside the profile returns user_not_found.
  • Key errors to distinguish: otp_unavailable (method disabled/channel missing), RATE_LIMITED (with retry_after), otp_invalid (wrong/expired code), user_not_found, ACCOUNT_SUSPENDED, NO_WORKSPACE, WORKSPACE_INACTIVE.

Logs to check

  • storage/logs/laravel.log — search for Mobile OTP email failed, mail transport errors, and provider exceptions for SMS.
  • Failed jobs (php artisan queue:failed) for queued notifications, digests and sequences.
  • Provider dashboards (SMTP provider, Twilio/Plivo, Firebase) — their side shows bounces and blocks the CRM cannot see.

When to escalate

  • Test emails consistently delivered to the platform inbox but never to one specific recipient domain — the recipient's mail admin needs to allowlist your sender.
  • Firebase OTP fails for every user despite enabled, seemingly-correct configuration.
  • OTP codes arrive but otp_invalid always follows — the stored hash chain or clock is suspect; a developer should inspect together with the provider timestamp.

Was this page helpful?