Skip to content

Supabase Auth errorSupabase sign-in fails with “Email not confirmed”

A user signs up, then can’t sign in: Supabase returns Email not confirmed, error code email_not_confirmed. Here’s what Supabase’s docs say causes it, in their own words, or hand it over at a fixed price.

Short answer

With Confirm Email on, which is the default on hosted Supabase projects, users have to click the link in the confirmation email before their first sign-in. If they never got the email, check sending first: the default email service allows 2 emails per hour on a best-effort basis, so set up custom SMTP for production. Make sure the link goes to your real site rather than localhost:3000, then resend the confirmation with supabase.auth.resend().

Why it happens, and the fix

  1. 01

    The user hasn’t clicked the confirmation link

    “Signing in is not allowed for this user as the email address is not confirmed.” Supabase, Auth error codes

    With Confirm Email on, a new user has to confirm their address before their first sign-in, and Supabase rejects the sign-in until they do. Tell users to check their inbox after signing up, and handle email_not_confirmed with a clear message and a resend button.

  2. 02

    It worked locally, then failed on the hosted project

    “On hosted Supabase projects, this is true by default. On self-hosted projects or in local development, this is false by default.” Supabase, Password-based Auth

    Email confirmation is on by default for hosted projects and off by default locally, so sign-in can work in development and fail after you deploy. The setting is on the Auth Providers page for hosted projects.

  3. 03

    The confirmation email never arrived

    “The service has a rate limit of 2 emails per hour, and availability is on a best-effort basis.” Supabase, Password-based Auth

    The signup confirmation needs an SMTP server to send it. Supabase’s default email service is for trying things out, so configure a custom SMTP server for production.

  4. 04

    The link opened localhost:3000

    “If you don't specify a redirect URL, the user is automatically redirected to your site URL. This defaults to localhost:3000, but you can also configure this.” Supabase, Password-based Auth

    Without a redirect URL in signUp(), the link goes to your Site URL, which defaults to localhost:3000. Set the Site URL to your live site, and add any redirect URL you pass to the Redirect URLs list.

  5. 05

    Send the confirmation again

    “Resends an existing signup confirmation email, email change email, SMS OTP or phone change OTP.” Supabase, JavaScript: resend

    Once sending and the links work, users who signed up earlier still need a new email. supabase.auth.resend() with type signup sends it again.

    const { error } = await supabase.auth.resend({
      type: 'signup',
      email: 'email@example.com',
      options: {
        emailRedirectTo: 'https://example.com/welcome'
      }
    })

Checked against the vendor’s docs on : Supabase docs: Auth error codes; Supabase docs: Password-based Auth; Supabase docs: Auth general configuration; Supabase docs: JavaScript resend.

Rather hand it over?

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

Related: Supabase email rate limit exceeded · Supabase auth emails going to spam · Supabase auth emails link to localhost · Supabase public storage bucket

Questions

More on this error

Should I turn off Confirm Email?

Supabase says that with Confirm Email disabled, it assumes the email doesn’t need to be verified to sign in and implicitly confirms the user’s email in the database. Decide whether your app needs verified addresses before you switch it off.

Where is the Confirm Email setting?

In the Supabase dashboard, under the email provider’s settings on the Auth Providers page for hosted projects. Self-hosted projects set it in the configuration file.

What do I need to give you to fix sign-in?

The app’s code and access to the Supabase project. We check the confirmation setting, email sending and redirect URLs, and send any code change as a pull request you review and deploy.

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.