FixedLaunchBack

fix guide

Supabase "Email link is invalid or has expired"

·

All fix guides

You click a confirmation, magic-link or password reset link and land on your app with "Email link is invalid or has expired" in the address bar. The address also holds error_code=otp_expired.

Supabase email links work once and run out of time. Either the link was already used, it got too old, or something opened it before you did. That something is often an email security scanner. Check these five in order.

1. The link is older than its time limit

Supabase's docs say magic links expire after 1 hour. The Email OTP expiration setting also applies to confirmation, password recovery, email change and invitation links. The docs strongly discourage a limit above 86,400 seconds, which is one day.

If someone opens an old email, ask for a new one. A user can only request a new link once every 60 seconds, so add a short wait after the click.

signs The link comes from an email that is hours or days old.

2. The link was already used

Supabase's docs say magic links are one-time use only. Clicking twice, opening the link on a phone and then on a desktop, or pressing back and clicking again all give this error on the second try.

Request a new link and click it once.

signs The first click worked or flashed past, and the second shows the error.

3. An email scanner opened the link first

Supabase's docs warn that some email providers have spam detection or security features that prefetch links in incoming emails. The scanner uses up the one-time link before the person clicks, and the person sees an error such as "Token has expired or is invalid".

The docs suggest two fixes, both made in the Authentication email templates. The first is to put {{ .Token }} in the template so the person gets a code, link to your own page where they type their email and the code, and check it with verifyOtp. The second is to link to your own page and pass the real link in a query parameter:

{{ .SiteURL }}/confirm?confirmation_url={{ .ConfirmationURL }}

On that page, a button holds the real link. A scanner that loads the page does not click the button, so the link stays unused.

signs The link fails on the very first click, especially for work or school addresses.

4. The link sends people to the wrong page

If the first click lands on a blank page or the login page with no sign you are logged in, people go back to the email and click again. The second click shows this error.

Supabase's docs say the Site URL is the default redirect when your code gives none, and that your redirect URLs must be in the allow list. Fix both using step 1 of Supabase login works locally but fails in production.

signs The first click lands on the wrong page without an error, and the error comes on the second click.

5. The password reset link

A reset link goes to the page set in redirectTo. Supabase's docs say it should be your change password page, and it must be in your Redirect URLs list. If that page is not ready for the link, people try the email again and hit the error.

If the reset page loads but shows "Auth session missing", read Supabase AuthSessionMissingError: Auth session missing.

signs Only the password reset email fails, or the reset page loads and the form never appears.

Test it like a new user

  1. Request a new link and click it once, within a minute. It signs you in or confirms the account.
  2. Click the same link a second time. You see a clear message and a way to ask for a new link.
  3. Send the email to a work or school address with a mail scanner, if you have one, and click it. It still works.
  4. Request a password reset and check the link opens your change password page on the live domain.

Common questions

What does error_code=otp_expired mean in Supabase?

The one-time code behind an email link has expired or was already used. Supabase's error list says to ask the user to sign in again. Request a new link, click it once, and check it is not older than the email expiry, which is 1 hour by default.

Why does my Supabase email link expire before I click it?

Some email providers have security features that open links in incoming emails before the person does. That uses up the one-time link. Supabase's docs suggest sending a code the person types in, or a link to your own page with a confirmation button.

How long do Supabase email links last?

One hour by default. The Email OTP expiration setting changes it, and it covers confirmation, password recovery, email change and invitation links. Supabase strongly discourages more than 86,400 seconds, which is one day. A person can request a new link once every 60 seconds.

Still stuck?

Not sure this is the cause? Paste your app's link into the free scan. It lists what a visitor's browser can see, like leaked keys and exposed files, worst first. The score is free; every fix as a prompt for your builder is $9, one-time.

Want a person to look inside? See the diagnosis

More fix guides

See all fix guides