Clerk: redirect loop after authentication [2026 fix]

Redirect loop caused by mismatched callback URL or missing signUpUrl/signInUrl props. Add exact domain to Clerk dashboard + configure routing props.

Clerk: Redirect Loop After Authentication [2am Emergency Fix]

TL;DR

Cause: Your Clerk dashboard callback URL doesn't match your app's actual domain, or <ClerkProvider> is missing signUpUrl/signInUrl props. Fix: Update callback URL in Clerk dashboard to exact domain + add routing configuration to ClerkProvider.

---

Exact Error Messages from Console

You'll see one or more of these:

``` Error: Redirect loop detected at redirectToSignIn (clerk.browser.js:4521:15) ```

``` warning: The <ClerkProvider> component does not have the signUpUrl prop. Please ensure you've set up your authentication URLs correctly. ```

``` GET http://localhost:3000/auth/callback?code=code_xxx 301 Moved Permanently → http://localhost:3000/auth/callback ```

``` Error: Cannot read property 'redirectUrl' of undefined at handleRedirectCallback (clerk.esm.js:8934:22) ```

``` warning: Clerk session is not ready yet. Skipping redirect. (infinite loop of this message) ```

---

The Problem: Broken Code

Scenario 1: Missing routing props on ClerkProvider

```jsx // ❌ BROKEN - redirect loop happens here import { ClerkProvider } from '@clerk/nextjs';

export default function RootLayout({ children }) { return ( <ClerkProvider> <html> <body>{children}</body> </html> </ClerkProvider> ); } ```

Scenario 2: Callback URL mismatch in dashboard

``` ❌ BROKEN in Clerk Dashboard: Callback URLs: http://localhost:3000/auth/callback Redirect URL (app): http://127.0.0.1:3000/auth/callback ↑ Different localhost vs 127.0.0.1 = infinite redirect ```

Scenario 3: Sign-in component without proper routing

```jsx // ❌ BROKEN - after authentication, nowhere to redirect to import { SignIn } from '@clerk/nextjs';

export default function LoginPage() { return <SignIn />; // Missing fallbackRedirectUrl } ```

---

The Fix: Exact Code Changes

Fix 1: Add routing props to ClerkProvider

```jsx // ✅ FIXED - routes properly configured import { ClerkProvider } from '@clerk/nextjs';

export default function RootLayout({ children }) { return ( <ClerkProvider signInUrl="/sign-in" signUpUrl="/sign-up" afterSignInUrl="/dashboard" afterSignUpUrl="/onboarding" > <html> <body>{children}</body> </html> </ClerkProvider> ); } ```

Fix 2: Update Clerk Dashboard callback URL

``` ✅ FIXED in Clerk Dashboard: Callback URLs: http://localhost:3000 https://yourdomain.com https://www.yourdomain.com ↑ Use EXACT domain your app runs on (no /auth/callback suffix needed) ```

Navigate to: Clerk Dashboard → Applications → [Your App] → Advanced → Allowed callback URLs

Fix 3: Add fallback redirect to SignIn component

```jsx // ✅ FIXED - explicit redirect path import { SignIn } from '@clerk/nextjs';

export default function LoginPage() { return ( <SignIn fallbackRedirectUrl="/dashboard" signUpUrl="/sign-up" /> ); } ```

Fix 4: Environment variables check

```bash

✅ FIXED - verify these exist in .env.local

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx CLERK_SECRET_KEY=sk_test_xxxxx 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 ```

---

Still Broken? Check These Too

1. Middleware routing conflict — If using middleware.ts in Next.js, ensure it doesn't redirect authenticated users back to /sign-in. Check that your publicRoutes array includes /sign-in and /sign-up.

2. Custom domain + localhost mismatch — Are you testing on localhost:3000 but Clerk dashboard only has production domain? Add http://localhost:3000 as callback URL for local development separately.

3. Session not yet loaded — The warning "session is not ready yet" means your redirect is firing before useAuth() hook completes. Wrap redirects in useEffect with isLoaded check from useClerk().

---

Version Note

These instructions apply to Clerk v4.x–v5.x (2025–2026). If using Clerk v3 or earlier, the @clerk/nextjs package structure differs slightly. Check your package.json version before applying.

---

Related Guides

  • [Clerk session undefined: fix useAuth hook](/guide=clerk-session-undefined)
  • [Next.js middleware auth setup](/guide=nextjs-auth-middleware)
  • ---

    Official Documentation

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

    ---

    Found a different variation? Drop it in the comments

    If you hit a redirect loop with a different stack (React, Vue, Remix) or hit this after updating Clerk versions, share the exact error message and setup in comments. This guide will be updated with additional scenarios.

    🔥 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