vercel/next.js · error
You can not have a '_next' folder inside of your public fold
Error message
You can not have a '_next' folder inside of your public folder. This conflicts with the internal '/_next' route. https://nextjs.org/docs/messages/public-next-folder-conflict
What it means
Thrown by the dev server's run() when an incoming request path starts with /_next and a directory literally named _next exists inside the project's public folder. Next.js reserves /_next as the internal asset route; a public/_next folder collides with it and would shadow or be shadowed by framework assets. The check uses fs.existsSync(pathJoin(publicDir, '_next')) and throws PUBLIC_DIR_MIDDLEWARE_CONFLICT.
Source
Thrown at packages/next/src/server/dev/next-dev-server.ts:652
): Promise<void> {
await this.ready?.promise
const { basePath } = this.nextConfig
let originalPathname: string | null = null
// TODO: see if we can remove this in the future
if (basePath && pathHasPrefix(parsedUrl.pathname || '/', basePath)) {
// strip basePath before handling dev bundles
// If replace ends up replacing the full url it'll be `undefined`, meaning we have to default it to `/`
originalPathname = parsedUrl.pathname
parsedUrl.pathname = removePathPrefix(parsedUrl.pathname || '/', basePath)
}
const { pathname } = parsedUrl
if (pathname!.startsWith('/_next')) {
if (fs.existsSync(pathJoin(this.publicDir, '_next'))) {
throw new Error(PUBLIC_DIR_MIDDLEWARE_CONFLICT)
}
}
if (originalPathname) {
// restore the path before continuing so that custom-routes can accurately determine
// if they should match against the basePath or not
parsedUrl.pathname = originalPathname
}
try {
return await super.run(req, res, parsedUrl)
} catch (error) {
const err = getProperError(error)
formatServerError(err)
this.logErrorWithOriginalStack(err)
if (!res.sent) {
res.statusCode = 500
try {
return await this.renderError(err, req, res, pathname!, {View on GitHub (pinned to 0ae8c72462)
Solutions
- Delete or rename the public/_next directory: `rm -rf public/_next`.
- Move its contents elsewhere (e.g. public/assets/) and update any references.
- Search the codebase/config for anything that generates public/_next and stop it.
- Restart the dev server after removing the directory.
Example fix
# before
public/
_next/
static/
# after
rm -rf public/_next
# use a non-reserved folder name if you need static assets
public/assets/ Defensive patterns
Strategy: validation
Validate before calling
import fs from 'fs'
import path from 'path'
// Fail fast in a prebuild script if the reserved folder exists
function assertNoPublicNext(publicDir: string) {
if (fs.existsSync(path.join(publicDir, '_next'))) {
throw new Error('public/_next conflicts with /_next route; remove it.')
}
} Prevention
- Never name a public asset folder _next.
- Add a CI check that public/_next does not exist.
- Review static-export/CMS outputs before copying into public.
When it happens
Trigger: A request to any /_next/* path (asset, chunk, etc.) is handled while public/_next exists on disk. The dev server detects the conflict and throws immediately, blocking the request.
Common situations: A user or scaffolding tool created public/_next (e.g. copying build output, a CMS export, or misreading docs). Renaming a folder to _next for organization. A static-export import that wrote into public. A previous `next export` whose output was copied into public.
Related errors
- Specified images.loaderFile does not exist at "${absolutePat
- Invalid handler fields configured for "cacheHandlers": ${inv
- Configuring Next.js via '${basename(unsupportedConfig)}' is
- Failed to read file contents of ${filename}.
- Failed to parse source map ${sourceMapFilename}.
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/0ddd20a432471d92.
Report an issue: GitHub.