Skip to content

If a user signs up with their phone number, verifying an email to add to their account doesn't work. #38482

@Musacoli

Description

@Musacoli

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When a user signs up with phone number (OTP) and later tries to add & verify an email to the same account during onboarding, the email verification fails with:

signup is not enabled for otp (or OTP signup is not enabled)

This happens even though OTP signups are enabled and work for both email-first and phone-first signups individually. The issue appears specific to the phone-first → add email path. The reverse flow (email-first → add phone) works fine.

To Reproduce

Auth configuration (Go to settings):

  • Email signups: Enabled
  • Phone signups: Enabled
  • External providers: Irrelevant to this repro
  • “Disable Signups”: Off
  • (Optional) “Confirm email change”: On (default behavior)

Steps:

  1. Sign up with phone (works)

    const { data, error } = await supabase.auth.signInWithOtp({
      phone: '+256XXXXXXXXX', // valid phone
      options: { channel: 'sms' }
    });
    // Receive & verify SMS OTP → user is created/signed in
  2. During onboarding, add an email to the same user
    (two common approaches—both end up failing):

    ** Try email OTP to “verify” the email (alternate path)**

    const { error } = await supabase.auth.signInWithOtp({
         email: formData.email,
         options: {
           shouldCreateUser: false // Don't create a new user, just verify email
         }
       });
    // Expect: treat as verification of email for existing user
    // Actual: error "signup is not enabled for otp"
  3. Observe error shown either directly in the response or surfaced after clicking the email confirmation link / attempting verifyOtp:

    signup is not enabled for otp
    

Control case (works as expected):

  1. Sign up with email (OTP/magic link).
  2. Add phone to the same user using updateUser({ phone }) and verify via SMS OTP.
    → No error. Phone is added successfully.

Expected behavior

  • A phone-first user should be able to attach and verify an email to their existing account.
  • signInWithOtp should trigger the normal email change/verification flow without being treated as a new OTP signup.
  • No “signup is not enabled for otp” error should occur in this linking scenario.

Screenshots

N/A (error is returned from API), but the message shown is:

signup is not enabled for otp

System information

  • OS: macOS 14.5 (also reproducible on Windows 11)
  • Browser: Chrome 126 (also reproducible in Safari & Firefox)
  • Project auth settings: Email signups ON, Phone signups ON, Disable signups OFF.

Additional context

  • This feels like the server interprets the email verification step for a phone-first existing user as an email OTP signup attempt, instead of an email change/attach flow.
  • Workarounds tried:
    • Ensured Email signups and Phone signups are enabled → still fails.
    • Reversing the flow (email-first → add phone) works, suggesting an asymmetry in linking logic.
  • Impact: Blocks onboarding for phone-first users who need to add an email for notifications, passwordless login, or account recovery.

Minimal repro gist (pseudo-app flow):

// 1) Phone signup
await supabase.auth.signInWithOtp({ phone: '+256XXXXXXXXX' });
// Verify SMS OTP out of band → session established

// 2) Add email to current user
// User receives email → clicks confirmation link / enters code
// Expected: email is verified & linked
// Actual: "signup is not enabled for otp"

Please advise whether this is a known limitation of phone-first accounts or a bug in how email verification is routed for existing users. Happy to provide project IDs & request IDs privately if that helps.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions