Skip to content
← Back to the blog
appsintegrations

Supabase not sending confirmation or reset emails? Fix it

Why Supabase Auth stops sending sign-up confirmation and password reset emails, from the built-in sender's limits to broken links, and how to fix each cause.

By Devonauts Team5 min read
Leer en español →
A hand holds a smartphone showing an empty email inbox, with a plant blurred behind it

Supabase usually stops sending confirmation and password reset emails because the project is still on its built-in email service, which only delivers to members of your Supabase team and allows 2 messages per hour. The fix is to connect your own SMTP provider (Resend, Postmark, Amazon SES, SendGrid, Brevo or similar) and then raise the email rate limit. If emails do arrive but the link fails, the cause is your URL settings or a mail scanner opening the link before your user does.

Below we go through each cause in the order worth checking, with where to look and how to confirm the fix.

Why does it work for me but not for my users?

Because the built-in sender only delivers to addresses that belong to your project's organization team. The Supabase custom SMTP docs say other addresses fail with the error Email address not authorized. When you test sign-up with your own email, it works. When a real customer signs up, nothing goes out.

The same page states the built-in service is best-effort, has no delivery guarantee and is meant for non-production use. Any app with real users needs its own SMTP.

Why do emails stop after a couple of tests?

The built-in sender allows 2 emails per hour for the whole project (Supabase notes this can change without notice). Every sign-up confirmation, magic link, password reset and email change counts. Two test sign-ups and the third person gets nothing until the hour passes.

On top of that, Supabase Auth has per-user limits. According to the Auth rate limits page, the defaults include a 60-second window before the same user can request another signup confirmation, password reset or magic link. When a limit is hit, the API answers 429 Too Many Requests. If your front end swallows that error, the user just sees "check your email" and nothing arrives.

How do I set up custom SMTP?

  1. Pick a provider and verify your domain there. The provider will ask you to add DNS records (SPF and DKIM, and ideally DMARC) for the domain you'll send from. Use a subdomain such as auth.yourapp.com or mail.yourapp.com if you also send marketing email, so the two don't share a reputation.
  2. Create SMTP credentials in the provider. You need a host, port (usually 587), username and password.
  3. Enter them in Supabase. In the dashboard's Authentication settings, enable custom SMTP and fill in the host, port, user, password, a sender address such as no-reply@yourapp.com and a sender name.
  4. Raise the email rate limit. Once custom SMTP is saved, Supabase applies a default of 30 emails per hour, which you can change on the Auth Rate Limits page. Set it to something that fits your expected sign-ups, with headroom for a launch day.
  5. Test with an address outside your team, such as a personal Gmail and a work Outlook address.

If your provider gives you an API rather than SMTP, or you want full control over the content and sending, Supabase also offers a Send Email Auth Hook. For most small apps, SMTP is simpler.

DNS records are where most custom setups go wrong. If mail is sent but lands in spam, read our guide on SPF, DKIM and DMARC for app emails.

Is "Confirm email" even turned on?

Check the Email provider settings in the Authentication section. If Confirm email is off, Supabase signs users in immediately and sends no confirmation at all. That's sometimes what a builder sets during prototyping. If it is on, users can't sign in until they click the link, so a broken sender blocks every new account.

Also note: if someone signs up again with an address that already belongs to a confirmed user, Supabase does not reveal that the account exists. Your app may show "check your email", but no new confirmation is sent. Point those users to password reset instead.

The link in the email is built from your project's Site URL and the redirect URL your code passes (for example emailRedirectTo on sign-up or redirectTo on resetPasswordForEmail). Both are controlled in Authentication > URL Configuration.

  • If the Site URL is still http://localhost:3000 or a preview address, links point there.
  • If your code passes a redirect URL that isn't in the Redirect URLs allow list, Supabase falls back to the Site URL.

Set the Site URL to your live domain and add every legitimate redirect, including preview domains if you need them. Our guide to login redirecting to localhost in Lovable shows this step by step.

When the email arrives and the user clicks quickly but still gets this error, the most common reason is link prefetching. The Supabase email templates docs explain that some email providers' security scanners open links in incoming mail. That uses up the one-time link before the person clicks it, something that can happen with company mailboxes that scan links for safety.

Two fixes are documented:

  1. Send a code instead of a link. Put {{ .Token }} in the template to include a 6-digit code the user types into your app.
  2. Link to a page with a button. Build your own link using {{ .TokenHash }} that opens a page in your app, and only verify the token when the user presses "Confirm". A scanner loads the page but doesn't press the button.

Other causes of this error: the user clicked an older email after requesting a newer one, or your email provider rewrote the links for click tracking. Supabase recommends turning click tracking off for auth emails.

How do I see what actually happened?

Open the Auth logs in your Supabase dashboard and look at the time of the failed attempt. You'll typically see one of: a rate-limit rejection, an SMTP error (wrong password, unverified sender), or a successful send. Then check your SMTP provider's activity log, which shows whether the message was delivered, bounced or marked as spam. Between those two logs you can usually locate the problem in a few minutes.

Quick answers

Can I raise the 2-per-hour limit without custom SMTP? No. The built-in sender's limit isn't meant to be raised; set up custom SMTP and adjust the limit there.

Do password reset emails have the same problem? Yes. Reset, magic link, invite and email change all go through the same sender and limits. Our guide to a secure password reset flow covers the rest of that flow.

Which SMTP provider should I choose? Any reputable transactional provider works. Choose one whose domain verification you can complete and whose free or entry tier fits your volume.

Should my app's other emails go through Supabase? No. Supabase SMTP is for auth emails. Receipts and notifications are better sent from your backend; see sending transactional emails from a Lovable app.

Still not arriving?

The free App Health Check is a quick first look at your live app from outside. If sign-up or login is blocking customers, our Supabase security review covers the whole Auth setup, and you can tell us what you're seeing.

Still stuck with your app?

Run the free health check on your app's URL, or get the $299 App Rescue Audit: a senior engineer reviews the code and sends you a written report in 2 business days.