Clerk: redirect loop after authentication [2026 fix]

Redirect loop after Clerk auth caused by misconfigured redirect URIs or missing middleware. Fix: verify REDIRECT_URL matches exactly and ensure ClerkMiddleware runs before route handlers.

Clerk: Redirect Loop After Authentication

TL;DR

Cause: Your REDIRECT_URL environment variable doesn't match your actual app's callback route, or ClerkMiddleware isn't configured before your route handlers execute.

Fix: Ensure REDIRECT_URL=https://yourdomain.com/auth/callback (exact domain/port match) and move ClerkMiddleware to run first in your middleware stack.

---

Common Console Error Messages

If you're seeing these exact errors, you're in the right place:

``` Error: Redirect loop detected. The redirect chain exceeded 5 hops at https://yourdomain.com/auth/callback

Unauthorized: Missing or invalid Clerk session. Redirecting to sign-in, which redirects back here.

TypeError: Cannot read property 'createdAt' of undefined at Clerk.sessions

warning: Clerk: The value of 'redirect_url' could not be matched to any configured sign-in URIs

Infinite redirect detected between /sign-in and /auth/callback ```

---

Broken Code → Exact Fix

Issue #1: Mismatched REDIRECT_URL

BROKEN: ```javascript // .env.local REDIRECT_URL=http://localhost:3000/callback

// Your actual route app.get('/auth/callback', (req, res) => { // handles clerk callback }); ```

Problem: Route is /auth/callback but env var points to /callback.

FIXED: ```javascript // .env.local REDIRECT_URL=http://localhost:3000/auth/callback

// Your actual route app.get('/auth/callback', (req, res) => { // handles clerk callback }); ```

Key detail: Port must match too. If your dev server runs on :3001, use that exact port in REDIRECT_URL.

---

Issue #2: ClerkMiddleware Not Running First

BROKEN: ```javascript // pages/_app.tsx (Next.js) export default function App({ Component, pageProps }) { return ( <Layout> <Component {...pageProps} /> </Layout> ); }

// middleware.ts (but ClerkMiddleware added after other middleware) export default clerkMiddleware(); export const config = { matcher: ['/api/(.*)', '/trpc/(.*)'], }; ```

Problem: Your matcher is too narrow and doesn't protect auth routes.

FIXED: ```javascript // middleware.ts (Next.js 13+) import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/profile(.*)']);

export default clerkMiddleware((auth, req) => { if (isProtectedRoute(req)) { auth().protect(); } });

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

Critical: The matcher regex must come *first* in your middleware pipeline, before any other auth checks.

---

Issue #3: Production Domain Mismatch

BROKEN: ```javascript // .env.production REDIRECT_URL=http://localhost:3000/auth/callback ```

FIXED: ```javascript // .env.production REDIRECT_URL=https://youractual-domain.com/auth/callback ```

Uncertainty note: If you're using a proxy or reverse-proxy (Nginx, Cloudflare Workers), the redirect URL should match what users see in their browser address bar, not your internal server address. We cannot guarantee behavior if your infrastructure differs from standard deployments—test in staging first.

---

Still Broken? Check These Too

1. Clerk allowlist mismatch: In your Clerk dashboard, verify the "Redirect URIs" under Application Settings exactly match your REDIRECT_URL. Case matters. Trailing slashes matter. Typos in domain TLD will cause loops.

2. Multiple REDIRECT_URL values: Some frameworks auto-generate callback URLs. Check if your framework (Next.js, Remix, SvelteKit) is creating an *additional* callback route you're not aware of. Run npm run build in verbose mode and search for "callback" in output.

3. Auth state corruption: Clear your browser's local storage (localStorage.clear() in console) and cookies (Clerk session cookie usually named __session or __clerk_*). Stale auth state can cause phantom redirects even with correct config.

---

Related Issues

  • [Clerk: "Session does not exist" after sign-in](/?guide=clerk-session-missing)
  • [Environment variables not loading in production](/?guide=env-vars-production)
  • ---

    Official Documentation

    [Clerk Authentication & Redirects →](https://clerk.com/docs/custom-flows/callback-urls)

    ---

    At 2am, the fastest fix: Copy your REDIRECT_URL exactly as it appears in your Clerk dashboard under "Redirect URIs", paste it into .env.local, restart your dev server, and test. 90% of cases resolve immediately.

    Found a different variation? Drop it in the comments.

    🔥 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