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

  1. Delete or rename the public/_next directory: `rm -rf public/_next`.
  2. Move its contents elsewhere (e.g. public/assets/) and update any references.
  3. Search the codebase/config for anything that generates public/_next and stop it.
  4. 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

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


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/0ddd20a432471d92. Report an issue: GitHub.