Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[@clerk/nextjs v7]: auth.protect() in Next.js 16 proxy redirects to current URL instead of sign-in page

Aperta
#8,302 3 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@jacekradko ci sta già lavorando.

Dal 13/5/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

needs-reproduction

Description

When using auth.protect() inside clerkMiddleware in a Next.js 16 app (proxy/Node.js runtime), unauthenticated users are redirected back to the current page URL instead of the sign-in page. Route protection is effectively bypassed — unauthenticated users can access protected pages.

Root Cause

Clerk resolves the sign-in redirect URL via NEXT_PUBLIC_CLERK_SIGN_IN_URL through process.env in two places:

clerkMiddleware.js:

const SIGN_IN_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL || "";
const signInUrl = resolvedParams.signInUrl || SIGN_IN_URL;

utils.js (handleMultiDomainAndProxy):

const signInUrl = (opts?.signInUrl) || SIGN_IN_URL;
return { proxyUrl, isSatellite, domain, signInUrl };

This signInUrl is spread over resolvedOptions in createAuthenticateRequestOptions, so requestState.signInUrl ends up as "" when the env var is unavailable.

In handleControlFlowErrors, when auth.protect() throws a sign-in redirect error, Clerk calls:

createRedirect({ signInUrl: requestState.signInUrl, baseUrl: clerkRequest.clerkUrl, ... })
  .redirectToSignIn({ returnBackUrl })

With signInUrl = "", new URL("", "https://example.com/dashboard") resolves to https://example.com/dashboard — the current page — and the user is never redirected to sign-in.

Why NEXT_PUBLIC_CLERK_SIGN_IN_URL is unavailable in the proxy

In Next.js 16, the proxy runs in the Node.js runtime (previously Edge in Next.js ≤15). NEXT_PUBLIC_* variables are inlined at build time into browser bundles, but in the Node.js proxy context they must be available via process.env at runtime. This works in standalone Next.js apps where next dev runs from the project root and loads .env files directly. In monorepo setups (e.g. pnpm workspaces + Turbo), process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL is not reliably populated in the proxy runtime, so SIGN_IN_URL falls back to "".

This was confirmed by testing with @clerk/nextjs 7.0.8 and 7.0.12 — both versions exhibit the same behavior. It is NOT a version regression.

Environment

  • @clerk/nextjs: 7.0.8, 7.0.12 (both affected)
  • next: 16.2.2 (proxy/Node.js runtime — proxy.ts replaces middleware.ts)
  • pnpm workspaces + Turbo monorepo

Steps to Reproduce

  1. Create a Next.js 16 app inside a pnpm workspace monorepo
  2. Add proxy.ts with standard route protection:
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";

const isPublicRoute = createRouteMatcher(["/sign-in(.*)", "/sign-up(.*)"]);

export default clerkMiddleware((auth, request) => {
  if (!isPublicRoute(request)) {
    auth.protect();
  }
});
  1. Set NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in in .env
  2. Run via Turbo (turbo run dev)
  3. Open an incognito window and navigate to a protected route

Expected Behavior

Unauthenticated users are redirected to /sign-in.

Actual Behavior

Error: NEXT_REDIRECT
  digest: 'NEXT_REDIRECT;replace;https://example.com/dashboard;307;',
  clerk_digest: 'CLERK_PROTECT_REDIRECT_TO_SIGN_IN',
  returnBackUrl: 'https://example.com/dashboard'

The page renders normally — protected content visible to unauthenticated users.

Workaround

Bypass auth.protect() and redirect manually using NextResponse.redirect():

import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";

const isPublicRoute = createRouteMatcher(["/sign-in(.*)", "/sign-up(.*)"]);

export default clerkMiddleware(async (auth, request) => {
  if (!isPublicRoute(request)) {
    const { userId } = await auth();
    if (!userId) {
      return NextResponse.redirect(new URL("/sign-in", request.url));
    }
  }
});
Lingua principale
TypeScript
Stelle
1.8k
Fork
472
Merge medio
2g 12h
PR unite (30g)
222

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di clerk/javascript

Tutte le issue di clerk/javascript

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.