Skip to content

Supabase Auth errorSupabase: “Email link is invalid or has expired” (otp_expired)

A new user clicks the confirmation link, or a password reset link, and lands on Email link is invalid or has expired, with otp_expired in the logs. Often they did nothing wrong: something opened the link before they did. Here’s what Supabase’s docs say, in their own words, and the fix, or hand it over at a fixed price.

Short answer

Supabase says the most common cause is email prefetching: a mail client or security tool, such as Safe Links in Microsoft Defender for Office 365, opens the link to check it and uses up the one-time token. Stop the link from consuming the token: put the 6-digit code {{ .Token }} in the email template, or link to a page of your own where the user enters it.

Why the link fails, and the fix

  1. 01

    An email scanner opened the link first

    “The most common reason for OTP tokens appearing expired or invalid before a user can even use them is email prefetching.” Supabase, OTP verification failures

    Security tools, often ones companies use, open links in incoming email to check them. That visit uses up the token, so when the user clicks, it has already gone.

  2. 02

    Send a code instead of a link

    “Use an email OTP instead by including {{ .Token }} in the email template” Supabase, Email templates

    Change the confirmation or reset template to show the 6-digit code, and add a screen where the user types it, which you check with supabase.auth.verifyOtp(). A scanner that opens links then has nothing to use up.

  3. 03

    Link to your own page, not to the token

    “Create your own custom email link to redirect the user to a page where they can enter their email and token to sign in” Supabase, Email templates

    To keep a button in the email, point it at a page on your site and let the user confirm from there, so opening the link doesn’t consume the token.

  4. 04

    Confirm it in the logs

    “If you see rapid 403 errors or otp_expired messages shortly after an email is sent, but before a user could reasonably click the link, it strongly suggests prefetching.” Supabase, OTP verification failures

    Look for 403 responses on the /verify endpoint in the API logs and otp_expired in the Auth logs, and compare their times with when the email went out.

Checked against the vendor’s docs on : Supabase troubleshooting: OTP verification failures (otp_expired); Supabase docs: Email templates.

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: Supabase Email not confirmed · Supabase email rate limit exceeded · Supabase auth emails going to spam · Sign in with Apple invalid_client

Questions

More on this error

Does the same fix work for password reset emails?

Yes. Supabase’s troubleshooting page is written around password resets: use a code, or a link that only opens a page where the user enters it.

Can a wrong clock cause it?

Supabase lists differences between the user’s device clock and the server’s time as a less frequent cause. Prefetching is the common one.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; we reply by email, usually within one business day.