The "phone_provider_disabled: Phone signups are disabled" error occurs when Supabase Auth attempts phone-based authentication but phone signups are not enabled in the project settings. This prevents users from signing up or logging in with phone numbers until phone authentication is properly configured and enabled.
The "phone_provider_disabled" error is a Supabase Auth error that indicates phone-based authentication is currently disabled for your project. When Supabase receives a request for phone sign-in, sign-up, or OTP verification, it checks whether the phone authentication provider is enabled in the project configuration. This error typically appears in development environments where phone authentication hasn't been set up yet, or in production when phone signups were intentionally disabled for security or maintenance reasons. Without enabling the phone provider, any attempts to use phone numbers for authentication will fail with this specific error code. The error serves as a configuration check to ensure that phone authentication is explicitly enabled before allowing phone-based operations, preventing accidental exposure of authentication endpoints that aren't ready for use.
First, enable phone authentication in your Supabase project settings:
1. Navigate to Supabase Dashboard:
- Go to your project → Authentication → Providers
- Scroll to the "Phone" section
2. Enable phone sign-in:
- Toggle "Enable phone sign-in" to ON (green)
- If you don't see this option, ensure you have the latest Supabase version
3. Configure SMS provider (if prompted):
- Select your SMS provider (Twilio, MessageBird, or custom)
- Enter required credentials (API keys, account SID, etc.)
- Save the configuration
# After enabling in dashboard, test with:
curl -X POST 'https://YOUR_PROJECT.supabase.co/auth/v1/otp' -H 'apikey: YOUR_ANON_KEY' -H 'Content-Type: application/json' -d '{"phone": "+1234567890"}'Check that all required phone authentication settings are correctly configured:
// Check current auth configuration
const { data: settings, error } = await supabase.auth.getSettings();
if (!error && settings) {
console.log('Phone auth enabled:', settings.disable_signup === false);
console.log('External providers:', settings.external);
// Phone should be in external providers if enabled
const phoneEnabled = settings.external?.phone === true;
console.log('Phone provider enabled:', phoneEnabled);
}Manual verification steps:
1. In Supabase Dashboard → Authentication → URL Configuration
2. Check "Site URL" is set (required for OTP redirects)
3. Verify "Enable phone sign-ins" is checked in Providers
4. Ensure no rate limiting is blocking phone authentication
5. Check project has necessary permissions for SMS sending
Phone authentication requires an SMS provider to send verification codes:
For Twilio:
1. Create a Twilio account if you don't have one
2. Get your Account SID and Auth Token
3. Purchase a phone number or use Messaging Service SID
4. In Supabase → Authentication → Providers → Phone:
- Select "Twilio" as provider
- Enter Account SID, Auth Token, and Messaging Service SID/Phone Number
- Save configuration
For MessageBird:
1. Create MessageBird account
2. Generate API key
3. Set up originator (sender ID)
4. In Supabase → Authentication → Providers → Phone:
- Select "MessageBird"
- Enter API key and originator
- Save configuration
Testing SMS configuration:
// Test phone authentication after configuration
const { data, error } = await supabase.auth.signInWithOtp({
phone: '+14155552671', // Test with your own number
options: {
channel: 'sms'
}
});
if (error) {
console.error('Error:', error.message);
console.error('Code:', error.code); // Should not be "phone_provider_disabled"
} else {
console.log('OTP sent successfully!');
}If phone authentication works in one environment but not another, check environment-specific settings:
Common environment issues:
1. Different Supabase projects per environment:
- Development, staging, and production may use different projects
- Ensure phone auth is enabled in ALL environments
2. Environment variables:ode
# .env.local (development)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# .env.production (production)
NEXT_PUBLIC_SUPABASE_URL=https://your-prod-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-prod-anon-key
3. **Conditional configuration in code**:javascript
// Bad: Disabling phone auth based on environment
const enablePhoneAuth = process.env.NODE_ENV !== 'production'; // Don't do this!
// Good: Use same configuration across environments
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
```
4. Database migrations affecting auth:
- Check if recent migrations modified auth schema
- Verify auth configuration survives database resets
Check if Row Level Security (RLS) policies or auth hooks are interfering:
1. Check RLS policies:
-- Check if any policies block phone auth
SELECT * FROM pg_policies
WHERE tablename = 'auth.users'
OR tablename LIKE 'auth.%';
-- Disable problematic policies temporarily for testing
ALTER TABLE auth.users DISABLE ROW LEVEL SECURITY;
-- Test phone auth
-- Re-enable: ALTER TABLE auth.users ENABLE ROW LEVEL SECURITY;2. Review auth hooks and Edge Functions:
- Check for Edge Functions intercepting auth requests
- Review any auth.stateChange callbacks
- Ensure hooks aren't blocking phone authentication
3. Test with minimal configuration:
// Create a clean test client
import { createClient } from '@supabase/supabase-js';
const testSupabase = createClient(
'https://your-project.supabase.co',
'your-anon-key',
{
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true
}
}
);
// Test with minimal options
const { error } = await testSupabase.auth.signInWithOtp({
phone: '+14155552671'
});When phone authentication is disabled, provide clear user feedback and alternatives:
// Client-side error handling
async function handlePhoneAuth(phoneNumber) {
try {
const { error } = await supabase.auth.signInWithOtp({
phone: phoneNumber,
options: { channel: 'sms' }
});
if (error) {
if (error.code === 'phone_provider_disabled') {
// Show user-friendly message
showErrorMessage(
'Phone authentication is currently unavailable. ' +
'Please use email or social login instead.'
);
// Offer alternatives
showAlternativeOptions(['email', 'google', 'github']);
return;
}
throw error;
}
// Success - show OTP input
showOtpInput();
} catch (err) {
console.error('Auth error:', err);
showGenericError();
}
}
// Alternative authentication flow
function showAlternativeOptions(providers) {
const availableProviders = {
email: () => supabase.auth.signInWithOtp({ email }),
google: () => supabase.auth.signInWithOAuth({ provider: 'google' }),
github: () => supabase.auth.signInWithOAuth({ provider: 'github' })
};
// Show buttons for available providers
providers.forEach(provider => {
if (availableProviders[provider]) {
createAuthButton(provider, availableProviders[provider]);
}
});
}User communication best practices:
- Clearly state phone auth is unavailable
- Provide immediate alternatives
- Link to status page if maintenance
- Offer contact method for support
## Phone Authentication Architecture in Supabase
### How Phone Auth Works
1. User initiates phone auth → Client calls signInWithOtp({ phone: '+123...' })
2. Supabase validates request → Checks if phone provider is enabled
3. If disabled → Returns phone_provider_disabled error immediately
4. If enabled → Generates OTP, sends via SMS, stores verification attempt
5. User enters OTP → Supabase verifies, creates session
### Configuration Storage
Phone authentication settings are stored in multiple places:
- Project config: In Supabase's internal configuration tables
- Auth schema: auth.config table controls enabled providers
- External: SMS provider credentials in encrypted storage
### Migration Considerations
When migrating Supabase projects or databases:
1. Project settings don't automatically migrate between projects
2. Phone auth config must be re-enabled in new projects
3. SMS provider credentials need to be reconfigured
4. Test thoroughly after migration
### Security Implications of Phone Auth
When to disable phone auth:
- During SMS provider outages
- When switching SMS providers
- Security incidents involving phone auth
- Maintenance windows
Risks of leaving disabled:
- Users expecting phone auth will get errors
- May break existing user flows
- Could violate accessibility requirements
### Monitoring Phone Auth Status
Set up alerts for:
- phone_provider_disabled error spikes
- SMS delivery failure rates
- Phone auth attempt volumes
- Configuration changes to auth providers
### Regional and Legal Considerations
- GDPR compliance: Phone numbers are PII (Personally Identifiable Information)
- Telecom regulations: Vary by country for SMS authentication
- Carrier restrictions: Some carriers block authentication SMS
- DLC/10DLC (US): Requires registration for business messaging
### Alternative Approaches
If phone auth needs to be temporarily disabled:
1. Maintenance mode page explaining outage
2. Feature flags to gradually disable/enable
3. Client-side detection to hide phone auth option
4. Server-side checks to return appropriate errors
email_conflict_identity_not_deletable: Cannot delete identity because of email conflict
How to fix "Cannot delete identity because of email conflict" in Supabase
mfa_challenge_expired: MFA challenge has expired
How to fix "mfa_challenge_expired: MFA challenge has expired" in Supabase
conflict: Database conflict, usually related to concurrent requests
How to fix "database conflict usually related to concurrent requests" in Supabase
phone_exists: Phone number already exists
How to fix "phone_exists" in Supabase
StorageApiError: resource_already_exists
StorageApiError: Resource already exists