This error occurs when attempting to update protected user fields for SSO-managed accounts in Supabase. Users authenticated via SAML SSO have immutable email and phone fields controlled by their identity provider.
This error appears when you try to modify certain user attributes (typically email, phone, or password) for a user account that is managed through Single Sign-On (SSO) authentication in Supabase. When users authenticate via SAML SSO or other enterprise SSO providers, Supabase marks specific fields as immutable to prevent conflicts between your application and the authoritative identity provider. The restriction exists because SSO-managed users derive their identity and authentication from an external provider (like Okta, Azure AD, or Google Workspace). Allowing local modifications to core identity fields would create synchronization issues and could compromise the security guarantees that SSO provides. The error typically occurs when using the admin.updateUserById() method or the regular auth.updateUser() method to change protected fields on SSO-authenticated user accounts.
Before attempting updates, verify the user's authentication method by examining their identities:
const { data: user } = await supabase.auth.admin.getUserById(userId);
// Check if user has SSO identities
const hasSSOIdentity = user.user.identities?.some(
identity => identity.provider === 'saml' || identity.provider === 'sso'
);
if (hasSSOIdentity) {
console.log('User is SSO-managed - email/phone/password are immutable');
}This prevents attempting operations that will fail for SSO users.
For SSO-managed users, update only the user_metadata and app_metadata fields, which remain mutable:
// Safe updates for SSO-managed users
const { data, error } = await supabase.auth.admin.updateUserById(
userId,
{
user_metadata: {
display_name: 'New Name',
avatar_url: 'https://example.com/avatar.png',
preferences: { theme: 'dark' }
},
app_metadata: {
roles: ['admin'],
subscription_tier: 'premium'
}
}
);Avoid setting email, phone, or password fields in the update payload.
If users need to change their email or phone number, direct them to update these fields in their SSO identity provider:
// Client-side check and user guidance
async function handleProfileUpdate(updates) {
const { data: { user } } = await supabase.auth.getUser();
const isSSOUser = user?.identities?.some(
identity => ['saml', 'sso'].includes(identity.provider)
);
if (isSSOUser && (updates.email || updates.phone)) {
// Show user message
return {
error: 'Email and phone are managed by your organization. Please contact your IT administrator to update these fields.'
};
}
// Proceed with allowed updates
return await supabase.auth.updateUser(updates);
}This provides clear guidance instead of confusing error messages.
Configure SAML attribute mapping to automatically sync user data from your identity provider:
{
"keys": {
"email": {
"name": "email"
},
"name": {
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
},
"phone": {
"name": "phone_number"
}
}
}Set this in your Supabase project's Authentication > Providers > SAML 2.0 settings. Changes made in the identity provider will automatically flow through on next login.
Create a helper function that handles updates differently based on authentication method:
async function updateUserProfile(userId: string, updates: {
email?: string;
phone?: string;
user_metadata?: Record<string, any>;
}) {
const { data: user } = await supabase.auth.admin.getUserById(userId);
const isSSOManaged = user.user.identities?.some(
id => ['saml', 'sso'].includes(id.provider)
);
if (isSSOManaged) {
// Only update metadata for SSO users
const { email, phone, ...safeUpdates } = updates;
if (email || phone) {
console.warn('Cannot update email/phone for SSO-managed user');
}
return await supabase.auth.admin.updateUserById(userId, safeUpdates);
} else {
// Allow all updates for non-SSO users
return await supabase.auth.admin.updateUserById(userId, updates);
}
}This prevents the error by filtering out immutable fields before the API call.
Understanding SSO Identity Management:
When a user authenticates via SAML SSO, Supabase creates an identity record with provider type 'saml'. The user's email and phone are derived from SAML assertions sent by the identity provider. To maintain data integrity and security, these fields cannot be modified locally.
Database-level restrictions:
The immutability is enforced at the auth service level, not just in the API. Direct database modifications to auth.users table for SSO-managed accounts may cause synchronization issues and authentication failures.
Handling email verification:
SSO users bypass email verification because their identity provider already verified their email. The email_confirmed_at timestamp is automatically set upon SSO authentication.
Multi-identity users:
If a user has both SSO and password-based identities linked (via identity linking), the SSO identity takes precedence for protected fields. The user must use their SSO provider to authenticate and cannot reset their password locally.
Service role considerations:
Even when using the service_role key with admin privileges, the immutability restriction applies. This is by design to prevent accidental data integrity violations.
Debugging in Dashboard:
In the Supabase Dashboard under Authentication > Users, SSO-managed users show their provider in the identities column. This visual indicator helps identify which users have field restrictions.
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