Clerk: redirect loop after authentication [2026 fix]
Redirect loop after Clerk auth caused by missing/misconfigured redirect URL in dashboard. Add exact callback URL to Allowed redirect URLs list.
Clerk: Redirect Loop After Authentication – Emergency Fix
TL;DR
Cause: Your Clerk dashboard's "Allowed redirect URLs" doesn't match your app's actual callback URL. Fix: Addhttp://localhost:3000/auth/callback (or your production equivalent) to Clerk Dashboard → Applications → [Your App] → Redirect URLs.---
Exact Console Error Messages
You'll see one or more of these in your browser console or server logs:
``` [Clerk] Error: Redirect URL 'http://localhost:3000/auth/callback' not in allowlist ```
``` Error: Invalid redirect_uri. The provided redirect_uri is not registered for this client. ```
``` Infinite redirect detected: /auth/callback → /auth/callback → /auth/callback ```
``` [Next.js] Unhandled Promise Rejection: ClerkRedirectError at /auth/callback ```
``` WARN [Clerk SDK] Redirect URI validation failed. Check your application settings. ```
---
Broken Code vs. Exact Fix
Scenario 1: Next.js 13+ App Router
❌ BROKEN (missing redirect URL configuration): ```typescript // app/auth/callback/route.ts import { handleCallback } from '@clerk/nextjs/app-router';
export const GET = handleCallback(); ```
```json // .env.local NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... CLERK_SECRET_KEY=sk_test_... ```
✅ FIXED (add redirect URL to Clerk Dashboard first, then update env):
1. Dashboard Step: Go to [Clerk Dashboard](https://dashboard.clerk.com) → Select your application → Settings → URLs → Add to "Allowed redirect URLs": ``` http://localhost:3000/auth/callback http://localhost:3000 https://yourdomain.com/auth/callback https://yourdomain.com ```
2. Code stays the same (no change needed if route is correct): ```typescript // app/auth/callback/route.ts import { handleCallback } from '@clerk/nextjs/app-router';
export const GET = handleCallback(); ```
Scenario 2: React SPA (Vite/Create React App)
❌ BROKEN (redirect URL mismatch): ```typescript // src/main.tsx import { ClerkProvider } from '@clerk/clerk-react';
export default function App() { return ( <ClerkProvider publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}> {/* App content */} </ClerkProvider> ); } ```
Dashboard has: http://localhost:5173
Your code redirects to: http://localhost:5173/auth/callback
Mismatch = Loop
✅ FIXED (add exact callback URL to dashboard):
Dashboard → Applications → [App] → Redirect URLs: ``` http://localhost:5173 http://localhost:5173/auth/callback https://yourapp.com https://yourapp.com/auth/callback ```
Code remains the same. The dashboard now allows both root and callback redirects.
---
Why This Happens
Clerk's OAuth flow requires the callback redirect URL to be explicitly whitelisted in your application settings. If your code tries to redirect to a URL not in the allowlist:
1. Clerk rejects the redirect 2. Your app catches the error and tries to redirect again (infinite loop) 3. Browser blocks it or shows endless redirect warnings
Common mismatches:
localhost:3000 vs. Production: yourdomain.com/auth/callback pathhttp:// vs. https:// protocol difference---
Still Broken? Check These Too
1. Environment Variables Not Reloaded
After updating .env.local, restart your dev server (Ctrl+C, then npm run dev). Clerk reads env vars at startup.
2. Browser Cache + Old Session
Open incognito window or hard-refresh (Ctrl+Shift+R). Clear cookies for your domain in DevTools → Application → Cookies.
3. CORS/Subdomain Mismatch
If your app lives on app.example.com but you registered example.com in Clerk, add both URLs to the allowlist: https://app.example.com and https://example.com.
---
Related Guides
---
Official Reference
📖 [Clerk Redirect URLs Documentation](https://clerk.com/docs/deployments/manage-domains#allowed-urls) 📖 [Clerk Next.js Integration Guide](https://clerk.com/docs/quickstarts/nextjs)
---
Final Checklist
http://localhost:PORT/auth/callback for developmenthttps://yourdomain.com AND https://yourdomain.com/auth/callback for productionCLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY match dashboard---
Note on versioning: This guide applies to Clerk SDK v4.x–v5.x (2024–2026). If using v3.x, verify your @clerk/nextjs or @clerk/clerk-react version with npm list @clerk/*. Behavior may differ in older versions.
Found a different variation? Drop it in the comments below—we update this guide with real 2am incident patterns.