Lovable password reset email not arriving: 5 reasons and how to check
You built the app in Lovable, wired up Supabase Auth, clicked "Forgot password," and… nothing. No email, no error on screen, just a spinner that finished and a user who's now locked out with no idea why.
This is one of the most common launch-blocking bugs in AI-built apps, and it almost never shows up while you're building - it shows up the day a real user hits it. Before anything else: check the spam/junk folder. That alone explains a surprising number of "it's not arriving" reports. If it's genuinely not arriving anywhere, one of the five things below is almost always the cause.
1No SPF, DKIM or DMARC on the sending domain
Every mail server that receives your password-reset email asks the same question before deciding where to put it: does this domain actually authorize this message? SPF, DKIM and DMARC are the DNS records that answer that question. Without them, a receiving server (Gmail, Outlook, anything) has no way to confirm the mail isn't spoofed - and transactional mail from an unauthenticated domain is graded as suspicious by default, which usually means the spam folder, sometimes silent dropping with no bounce at all.
This is extremely common on apps built with Lovable/Bolt/Cursor, because the domain gets connected for the website long before anyone thinks about email DNS.
How to check
dig TXT yourdomain.com # look for "v=spf1 ..." dig TXT _dmarc.yourdomain.com # look for "v=DMARC1 ..."
DKIM depends on your email provider's selector, so it's harder to guess manually. The fastest way: run ShipClarity's free scanner against your domain - it checks all three records in about 20 seconds and tells you exactly which one is missing, no login required.
2Still on Supabase's shared email sender
By default, Supabase Auth sends confirmation and password-reset mail through its own built-in email service. Supabase's own documentation is explicit about this: it's meant for development and testing, not production traffic. It's shared across a large number of projects, its sending reputation is out of your control, and it's aggressively rate-limited (see next point).
Most vibe-coded apps never change this, because the reset flow works fine in testing - one email, one developer, no rate limit pressure - and the gap only appears once real users start signing up.
How to check
In the Supabase dashboard: Authentication → Sign In / Providers → SMTP Settings. If "Enable Custom SMTP" is off, you're on the shared sender. The fix is connecting a real transactional provider (Resend, Postmark, SendGrid, Amazon SES) with its own authenticated sending domain - which also resolves point 1 at the same time.
3Hit the default sender's rate limit, silently
Even while still on the shared sender, Supabase caps how many auth emails a project can send per hour - a small number, intended for development traffic. The app's UI almost always shows "Check your email!" regardless of whether the email was actually queued, because that response comes from the API call succeeding, not from mail delivery. If a user (or a tester) clicks "resend" a few times while debugging something else, the limit is gone for the rest of the hour and every subsequent attempt looks identical from the outside: a success message and no email.
How to check
Supabase dashboard → Logs → Auth Logs, filtered to the relevant time window. Repeated reset requests in a short span with no matching "email sent" event is the signature of this one. Waiting an hour and trying once, cleanly, is the fastest way to confirm or rule it out.
4Site URL / Redirect URL misconfigured
Supabase Auth generates the actual reset link using the Site URL and the Redirect URLs allowlist set in the project's Auth configuration. If those still point at a Lovable preview URL from before the app moved to a custom domain, one of two things happens: the email fails to send because Supabase can't build a valid link, or - more confusingly - the email arrives and the link works, but it drops the user on the wrong (old, no-longer-live) domain, which looks identical to "the reset flow is broken" from the user's side.
How to check
Authentication → URL Configuration in the Supabase dashboard. Confirm both the Site URL and every redirect URL your app actually uses in production are listed, exactly matching scheme and domain (https://app.yourdomain.com, not the Lovable-generated one).
5The email arrives, but as spam - content, not authentication
Even with SPF/DKIM/DMARC correctly set up, content-level spam filtering still applies. The usual culprits in auto-generated transactional templates: a generic sender name like noreply@ with no display name, an HTML-only email with no plain-text alternative, and subject lines that read as urgent or promotional ("URGENT: Reset your password now!!"). None of these are dealbreakers on their own, but stacked together they push a message toward the spam folder even on a perfectly authenticated domain.
How to check
Send the exact reset email template to a free tool like mail-tester.com - it gives a 0-10 score with a line-by-line breakdown of what's dragging it down, separate from the DNS-level checks in point 1.
Check your own setup in 20 seconds
ShipClarity's free scanner checks SPF, DKIM and DMARC on your domain automatically - no login, no signup. It's exactly the first check from this article, already run for you.
Run the free scan See what a full audit coversA full password-reset walkthrough - request, receive, click, land on the right page, log in - is one of the manual checks in a Pre-Launch Audit. The free scanner can only see what's visible from outside, without an account; it can't click the actual link.