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