This error occurs when Supabase Auth fails to authenticate a user due to invalid email or password. The error intentionally doesn't distinguish between wrong passwords and non-existent users for security reasons.
When you attempt to sign in to a Supabase application using the `signInWithPassword()` method, the authentication system verifies the provided email and password against records in the Supabase Auth database. The "invalid_credentials" error is returned when the authentication fails. For security purposes, Supabase does not distinguish between two scenarios: (1) a user tried to log in with a correct email but wrong password, or (2) a user tried to log in with an email that doesn't exist in the system. This is intentionalโit prevents attackers from using login attempts to enumerate valid email addresses.
Double-check the email address and password for typos. Common mistakes include:
- Extra spaces before/after the email
- Caps Lock accidentally enabled
- Password with special characters typed incorrectly
Trim whitespace from inputs in your code:
const email = userInput.email.trim().toLowerCase();
const password = userInput.password;
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});If the user has forgotten their password, provide a password reset option. This is the most user-friendly approach:
const { data, error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/auth/callback`,
});
if (error) console.error('Reset error:', error);
else alert('Check your email for password reset link');The user will receive a reset link in their email to create a new password.
If you need to distinguish between wrong password and non-existent user, query your users table:
// After catching 'invalid_credentials' error
const { data: users } = await supabase
.from('users') // or your users table name
.select('id')
.eq('email', email)
.single();
if (!users) {
// User does not exist in system
console.log('Email not found - user needs to sign up');
} else {
// User exists but password is wrong
console.log('Email exists - password is incorrect');
}Note: This only works if you store user emails in a custom users table. Supabase Auth itself doesn't expose this information.
If a user originally signed up with OAuth (GitHub, Google, etc.), they cannot log in with a password. Verify their signup method:
// Get current session to see linked identities
const { data: { user } } = await supabase.auth.getUser();
console.log(user?.identities); // Shows OAuth providers used
// If they signed up with GitHub but try password login, explain:
// "You signed up using GitHub. Please sign in with GitHub instead."Ensure your Supabase client is initialized with correct credentials:
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
'https://YOUR_PROJECT_ID.supabase.co',
'YOUR_PUBLIC_ANON_KEY'
);If credentials are mismatched or pointing to the wrong project, all auth calls will fail. Check your .env file matches your Supabase project settings.
By design, Supabase does not differentiate between "wrong password" and "user does not exist" in the error response. This security-first approach prevents account enumeration attacks where attackers could discover valid email addresses in your user base.
If your application requires distinguishing these cases, you'll need to implement additional logic by querying your custom users table after catching the error. However, be mindful of rate limiting to prevent attackers from using this as a reconnaissance tool.
For self-hosted Supabase deployments, ensure your JWT secret is properly configured (at least 32 characters, using alphanumeric characters). Malformed JWT secrets can cause authentication issues even with correct credentials.
email_address_not_authorized: Email sending to this address is not authorized
Email address not authorized for sending in Supabase Auth
reauthentication_needed: Reauthentication required for security-sensitive actions
Reauthentication required for security-sensitive actions
no_authorization: No authorization header was provided
How to fix "no authorization header was provided" in Supabase
otp_expired: OTP has expired
How to fix 'otp_expired: OTP has expired' in Supabase
bad_oauth_state: OAuth state parameter is missing or invalid
How to fix 'bad_oauth_state: OAuth state parameter missing' in Supabase