Supabase Auth: Fix "Invalid login credentials" Error

7. August 2026 approx. 4 min read Supabase
Contents 11

Your login form looks fine, email and password seem correct – yet Supabase Auth responds with:

AuthApiError: Invalid login credentials

Or in the Network tab: 400 with error_description: "Invalid login credentials". Here are the most common causes and the fixes that reliably worked for me.

The Problem: What "Invalid login credentials" Really Means

For security reasons Supabase does not tell you whether the email or the password is wrong. That single message covers several cases:

  • Wrong password or a typo in the email
  • User does not exist (yet) in this project
  • Email not confirmed yet (Enable email confirmations)
  • Wrong project / wrong keys in the client
  • User created via OAuth, but login attempted with password

The Solution: Narrow Down the Cause

Step 1: Check the User in the Dashboard

Under Authentication → Users, search for the email:

  • No row → sign-up failed or different project
  • Row without confirmation → confirmation still pending
  • Provider only google/github → password login will not work

Step 2: Call Sign-in Correctly

const { data, error } = await supabase.auth.signInWithPassword({
  email: email.trim().toLowerCase(),
  password,
})

if (error) {
  console.error(error.message, error.status)
  // "Invalid login credentials" → see checklist below
}

Use trim() and keep email casing consistent between sign-up and sign-in.

Step 3: Email Confirmation

If confirmations are enabled and the user is unconfirmed, login can fail depending on your settings. For debugging, temporarily disable confirmations or confirm the user in the dashboard:

-- Local/dev only: confirm a user manually
UPDATE auth.users
SET email_confirmed_at = now()
WHERE email = 'test@example.com';

Step 4: Verify Project URL and Keys

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
)

Mixed projects (staging vs production) are a classic: sign-up lands in project A, login hits project B.

Common Mistakes

  • signUp instead of signIn: a second sign-up with the same email feels like a login failure.
  • Whitespace in inputs: mobile autofill often adds trailing spaces.
  • Identity linking: user registered with Google, then tries email/password.
  • Custom SMTP / redirect URLs: confirmation mail never arrives → account stays unconfirmed.

Complete Login Example with Clear Errors

async function login(email, password) {
  const { data, error } = await supabase.auth.signInWithPassword({
    email: email.trim().toLowerCase(),
    password,
  })

  if (error) {
    if (error.message === 'Invalid login credentials') {
      return {
        ok: false,
        hint: 'Check email/password, confirmation, and auth provider in the dashboard.',
      }
    }
    if (error.message.includes('Email not confirmed')) {
      return { ok: false, hint: 'Confirm the email or unlock the user in the dashboard.' }
    }
    return { ok: false, hint: error.message }
  }

  return { ok: true, session: data.session }
}

Troubleshooting Checklist

  1. ✅ User present under Authentication → Users?
  2. email_confirmed_at set (if confirmations are on)?
  3. ✅ Login method matches provider (password vs OAuth)?
  4. ✅ URL + anon key belong to the same project as the user?
  5. ✅ Email trimmed / password free of autofill artifacts?

Conclusion

Invalid login credentials is intentionally vague. With a dashboard check, correct signInWithPassword, a confirmed email, and the right project keys, you usually find the cause in a few minutes.

Additional Resources

Still seeing the message with the correct password? Leave a comment – often it is confirmation or the wrong provider.

Comments