Clerk: redirect loop after authentication [2026 fix]

Redirect URI mismatch or missing signUpUrl causes infinite loop. Add exact redirect URIs to Clerk dashboard + configure signUpUrl in middleware.

Clerk: Redirect Loop After Authentication [2am Fix]

TL;DR

Cause: Your redirect URI in Clerk dashboard doesn't match your app's actual callback URL, or signUpUrl is missing from your middleware configuration.

Fix: Add http://localhost:3000/auth/callback (dev) and https://yourdomain.com/auth/callback (prod) to Clerk dashboard under "Redirect URLs," then set signUpUrl explicitly in your ClerkProvider or middleware.

---

Exact Error Messages You'll See

``` 1. "Error: Invalid redirect_uri. The redirect_uri parameter does not match any of the configured redirect URIs for this application."

2. "GET /auth/callback?code=xyz&state=abc 307 - Redirect loop detected"

3. "[Clerk] Redirect called but destination URL is not whitelisted"

4. "Error: The redirect URL is missing the signUpUrl configuration. Redirecting to sign-up but no URL found."

5. "POST /api/auth/callback - ERR_TOO_MANY_REDIRECTS" ```

---

Broken Code vs. Exact Fix

Issue 1: Missing Redirect URIs in Dashboard

❌ BROKEN (implicit, nothing in code—it's a config issue) ```javascript // Your app redirects to this after auth: // http://localhost:3000/auth/callback

// But Clerk dashboard has NO redirect URIs configured // or only has: http://localhost:3000 ```

✅ FIXED ``` Clerk Dashboard → Applications → [Your App] → Redirect URLs

Add BOTH:

  • http://localhost:3000/auth/callback
  • https://yourdomain.com/auth/callback
  • Save and wait 30 seconds for propagation. ```

    Issue 2: Missing signUpUrl in ClerkProvider

    ❌ BROKEN ```javascript // pages/_app.tsx or app/layout.tsx import { ClerkProvider } from '@clerk/nextjs';

    export default function MyApp({ Component, pageProps }) { return ( <ClerkProvider> <Component {...pageProps} /> </ClerkProvider> ); } ```

    ✅ FIXED ```javascript import { ClerkProvider } from '@clerk/nextjs';

    export default function MyApp({ Component, pageProps }) { return ( <ClerkProvider signUpUrl="/sign-up" signInUrl="/sign-in" afterSignInUrl="/dashboard" afterSignUpUrl="/onboarding" > <Component {...pageProps} /> </ClerkProvider> ); } ```

    Issue 3: Middleware Redirect Misconfiguration

    ❌ BROKEN ```javascript // middleware.ts import { authMiddleware } from '@clerk/nextjs';

    export const config = { matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'] };

    export default authMiddleware(); ```

    ✅ FIXED ```javascript // middleware.ts import { authMiddleware } from '@clerk/nextjs';

    export const config = { matcher: [ '/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)', '/(auth)(.*)' // Explicitly allow auth routes ] };

    export default authMiddleware({ publicRoutes: [ '/sign-in', '/sign-up', '/auth/callback', // Add this line '/', '/api/public(.*)' ], ignoredRoutes: ['/api/webhooks(.*)'] }); ```

    ---

    Step-by-Step Resolution at 2am

    1. Check Clerk Dashboard (5 min) - Go to https://dashboard.clerk.com - Select your application - Under "API Keys & URLs," verify "Redirect URLs" section - Your localhost entry should be http://localhost:3000/auth/callback exactly - Production entry should match your actual domain

    2. Clear Browser Cache (2 min) ```bash # Windows: Ctrl+Shift+Delete # Mac: Cmd+Shift+Delete in Chrome, Cmd+Option+E in Safari # Or in code: ``` Delete __session and __clerk_db_jwt cookies manually

    3. Check Environment Variables (3 min) ```bash # .env.local must have: NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... CLERK_SECRET_KEY=sk_test_... NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding ```

    4. Restart Dev Server (1 min) ```bash npm run dev # or yarn dev ```

    ---

    Still Broken? Check These Too

    1. CORS/Cookie Domain Mismatch — If testing across subdomains (api.example.com vs app.example.com), Clerk cookies won't match. Set cookieDomain in Clerk instance config: [CORS troubleshooting guide](/?guide=clerk-cors)

    2. Stale Clerk Cache — Clerk caches redirect URIs for ~5 minutes. If you just updated the dashboard, wait 5 minutes and clear browser cache again. Force-refresh with Ctrl+Shift+R.

    3. Auth Callback Route Missing — Ensure you have /auth/callback route implemented. In Next.js App Router: create app/auth/callback/route.ts with export const GET = handleClerkCallback(). In Pages Router: create pages/auth/callback.tsx with empty component. [Callback route setup](/?guide=clerk-callback-route)

    4. Multiple Clerk Instances — If using Clerk in multiple places without shared context, each creates separate sessions. Use single <ClerkProvider> wrapper at root only.

    5. Outdated @clerk/nextjs Package — Version 4.x+ has breaking changes. Check: npm list @clerk/nextjs. If below 4.25.0, update: npm install @clerk/nextjs@latest

    ---

    Official Documentation

    [Clerk Next.js Authentication Redirect Setup](https://clerk.com/docs/quickstarts/nextjs)

    ---

    Found a different variation? Drop it in the comments below.

    If your redirect loop manifests differently (e.g., infinite /sign-in loops, custom domain issues, or API-based auth), reply with:
  • Exact error message
  • Your Clerk SDK version
  • Next.js/framework version
  • How you're initiating sign-in (button, automatic, webhook)
  • Helps us catch edge cases!

    🔥 0d
    LIVE
    ↓ PlanetScale rage spiking •⚠ Vercel pricing complaints •↑ Railway gaining fast •↑ Supabase happiness rising •↑ Resend loved by devs •↓ PlanetScale rage spiking •⚠ Vercel pricing complaints •↑ Railway gaining fast •↑ Supabase happiness rising
    DEVELOPER PAIN RADAR // Loading...

    Developers complain.
    Opportunities appear.

    We track what developers are struggling with today — and what opportunities that creates.

    —
    guides today
    —
    avg happiness
    🔥 Pain
    📖 Guides
    🔭 Explore
    👤 Mine
    🔥 Pain Radar — rage scores today
    ↗ share
    💡 Opportunity Feed — pain = market gap
    📈 Tool Momentum
    all scores →
    📖 Latest Guide
    all guides →
    📖 All Guides
    📊 Tool Scores
    + Submit
    📰 Hacker News
    ➕ Submit a Tool
    ← back