Supabase error otp_expired (otp_expired) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Request a fresh code with signInWithOtp and have the user retry quickly. If that does not apply, verify the token type matches the flow (email vs SMS vs phone) — the full checklist is below.
Error code: otp_expired
Official name: otp_expired
Service: Supabase
OTP code for this sign-in has expired. Ask the user to sign in again.
const { error } = await supabase.auth.verifyOtp({
email,
token: code,
type: 'email',
})
if (error?.code === 'otp_expired') {
// resend and let the user retry with the new code
await supabase.auth.signInWithOtp({ email })
}
Auto-resending on otp_expired keeps the UX smooth, but respect the email rate limit.
Detect otp_expired and immediately offer a resend with a countdown.
if (error?.code === 'otp_expired') {
startCountdown(60)
showToast('Code expired - a new one was sent')
await supabase.auth.signInWithOtp({ email })
}
Most often this happens when magic link or OTP code used after its expiry window, or when six-digit code typed too slowly (SMS OTP windows are short).
Request a fresh code with signInWithOtp and have the user retry quickly.
This page documents fixes for: supabase-js.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official Supabase documentation linked below and adds practical troubleshooting guidance on top.