Auth Issues
Diagnosis and resolution guide for authentication and authorization problems.
Login redirect loop
Symptoms
- Browser redirects between web app and auth app infinitely
- URL alternates between
localhost:3000andlocalhost:3004
Root cause
Auth URL mismatch between the web app and auth app configuration.
Diagnosis
- Check
AUTH_BASE_URLin.env.local - Verify the auth app is running on the expected port
- Check browser cookies/localStorage for stale tokens
Fixes
- Ensure
AUTH_BASE_URL=http://localhost:3004matches the running auth app - Clear browser storage: DevTools → Application → Clear site data
- Restart both web and auth apps
Prevention
- Keep
.env.localin sync when changing ports - Use
pnpm nx run-many -t serve -p web,authto start both together
JWT expired / invalid token
Symptoms
401 Unauthorizedon API callsJWT expirederror in console- User unexpectedly signed out
Root cause
Access token expired and refresh failed, or token was corrupted.
Diagnosis
- Open DevTools → Application → Local Storage
- Find
sb-*-auth-token - Decode the
access_tokenat jwt.io - Check the
expfield
Fixes
Clear and re-login:
DevTools → Application → Local Storage → ClearThen navigate to the login page.
Check Supabase status:
bashpnpm supabase statusVerify time sync — JWT validation fails if server and client clocks differ significantly
Prevention
- The Supabase client auto-refreshes tokens; ensure the
onAuthStateChangelistener is connected - Set reasonable token expiry in
supabase/config.toml
OAuth callback failures
Symptoms
- After clicking "Sign in with Google/GitHub," the page shows an error
- Redirect URI mismatch error from the OAuth provider
Root cause
The OAuth app's redirect URI does not match the Supabase callback URL.
Diagnosis
- Check the error message from the OAuth provider
- Verify redirect URIs in:
- Google Cloud Console / GitHub Developer Settings
supabase/config.toml(auth.external.*section)
Fixes
Local development redirect URI:
http://127.0.0.1:54321/auth/v1/callbackProduction redirect URI:
https://your-supabase-project.supabase.co/auth/v1/callbackEnsure the OAuth app status is not "testing" (Google limits test apps to 100 users)
Prevention
- Document redirect URIs in your project setup guide
- Test OAuth flows after every Supabase URL change
Permission denied (RLS)
Symptoms
- Queries return empty arrays when data exists
42501PostgreSQL error codepermission denied for tableerrors
Root cause
Row-Level Security policies block the current user from accessing the data.
Diagnosis
sql
-- Check current user
SELECT auth.uid();
-- Check policies on the table
SELECT * FROM pg_policies WHERE tablename = 'your_table';
-- Test with service role (bypasses RLS)
-- Use Supabase Studio or psql with the service role connection stringFixes
- Verify the user owns the data — check
owner_idoruser_idcolumns - Check workspace membership — user may not be in the required workspace
- Review RLS policies — ensure the
USINGclause covers your use case - Use service role for debugging — temporarily test with the service role key
Prevention
- Write RLS policies with test cases
- Use
supabase test dbto validate policies against test data
API key issues
Symptoms
Invalid API keyerrorapikeyheader missingPGRST301(JWT required)
Root cause
Wrong or missing Supabase anon key in the environment configuration.
Fixes
- Run
pnpm supabase statusand copy theanon key - Update
SUPABASE_ANON_KEYin.env.local - Restart the dev server
Prevention
- After
pnpm supabase stop && pnpm supabase start, the keys may change - Script the key extraction:
pnpm supabase status | grep anon