Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware()
Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware(). Please ensure the following:
clerkMiddleware() is used in your Next.js middleware or proxy file.
Your middleware or proxy matcher is configured to match this route or page.
If you are using the src directory, make sure the middleware or proxy file is inside of it.
If you've verified your configuration and are still seeing this error, there may be a runtime issue or a problem communicating with Clerk.
For more details, see https://clerk.com/err/auth-middlewareOn Next.js 15 and earlier, the message says middleware in place of middleware or proxy.
Why this occurred
This error occurs when a request that isn't covered by clerkMiddleware() returns a 404 in a Clerk + Next.js App Router setup. It commonly appears when the clerkMiddleware() helper is configured not to run on static asset routes, which is part of the default setup. It can happen for the following reasons:
- Missing
<ClerkProvider>: The<ClerkProvider>is not wrapped around the component tree where Clerk components are used. - Incorrect path: A typo or incorrect path is used in a static asset request.
Ways to fix this
Missing <ClerkProvider>
Choose this when <ClerkProvider> isn't wrapping the component tree where Clerk components are used. This is the most common cause — auth()
The <ClerkProvider> component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with <ClerkProvider> to make authentication globally accessible. See the reference docs for other configuration options.
Solution
Ensure that <ClerkProvider> is set up at a higher level in your component hierarchy than any Clerk components like <UserButton />, <Show>, or others. The Next.js quickstart shows how you can do this in your root layout.
import { ClerkProvider } from '@clerk/nextjs'
import { Geist, Geist_Mono } from 'next/font/google'
import './globals.css'
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
})
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
})
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en" className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}>
<body className="min-h-full flex flex-col">
<ClerkProvider>{children}</ClerkProvider>
</body>
</html>
)
}Incorrect path
Choose this when <ClerkProvider> is configured correctly but a request still triggers the error. This happens because when auth() was called, clerkMiddleware() didn't run on the request. This can occur if a request is made to a non-existent static asset. Static asset requests are excluded by the matcher Clerk provides and often by other matchers in your Middleware, so clerkMiddleware() doesn't run for them. A typo or incorrect path is usually the problem in these cases.
For example,
- A user accesses
/dashboard, which is a valid page and matched route. - That page includes an
<img>tag with asrcpointing to an invalid path. - A 404 error is triggered because of the invalid static asset request.
- Next.js serves the 404 response.
- The 404 page is rendered within the root layout — that's where Next.js injects their 404 page/component.
- Since
<ClerkProvider>is usually placed in the root layout, it runs, but because the request didn't match the middleware matcher,clerkMiddleware()never executed. As a result,<ClerkProvider>attempts to callauth()without context, leading to one of these outcomes:- A
500or404error in your browser's network tab. GET /{non-existing-path}.{static-asset-extension} 500 | 404in your terminal or logs.- The following Clerk error in the console:
x [Error: Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware(). Please ensure the following: clerkMiddleware() is used in your Next.js middleware or proxy file. Your middleware or proxy matcher is configured to match this route or page. If you are using the src directory, make sure the middleware or proxy file is inside of it. If you've verified your configuration and are still seeing this error, there may be a runtime issue or a problem communicating with Clerk. For more details, see https://clerk.com/err/auth-middleware ] { digest: '3346914516' }
- A
Solution
Select the appropriate solution based on your use case:
The ideal solution is to fix any incorrect asset paths, as this is the root cause of the error and the cleanest fix. Ensure that all images, icons, or files are requested using valid URLs. When these requests succeed, no 404 is triggered, and the Clerk provider context works as expected.
This fix will prevent the Clerk error, as it moves <ClerkProvider> from the root layout. However, it does not resolve the underlying issue, which is a reference to a missing static asset. Your app will still have a 404 network request for the missing asset.
If you want to protect your app against similar issues in the future or want to ensure that system-level errors (like 404s) don't rely on Clerk, you can refactor your layout structure.
By moving <ClerkProvider> into a subfolder layout, you allow 404 pages and other global error routes to render without needing Clerk's context.
Before
app/
layout.ts // includes <ClerkProvider />After
app/
layout.ts // base layout without Clerk
(in-app) // virtual folder - doesn't impact routing
layout.ts // includes <ClerkProvider />
page.tsxHere's an example of what the new Clerk layout would look like in this case:
import { ClerkProvider } from '@clerk/nextjs'
export default function AppLayout({ children }: { children: React.ReactNode }) {
return <ClerkProvider>{children}</ClerkProvider>
}Or loading Clerk built-in components:
import { ClerkProvider, Show, SignInButton, SignUpButton, UserButton } from '@clerk/nextjs'
export default function AppLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<header className="flex justify-end items-center p-4 gap-4 h-16">
<Show when="signed-out">
<SignInButton />
<SignUpButton />
</Show>
<Show when="signed-in">
<UserButton />
</Show>
</header>
{children}
</ClerkProvider>
)
}This ensures the root layout (which handles top-level errors like 404s) does not rely on Clerk, avoiding the middleware mismatch error entirely.
Feedback
Last updated on