vercel/next.js · error

Specified images.loader property (${images.loader}) also req

Error message

Specified images.loader property (${images.loader}) also requires images.path property to be assigned to a URL prefix.
See more info here: https://nextjs.org/docs/api-reference/next/legacy/image#loader-configuration

What it means

Built-in non-default image loaders (cloudinary, akamai, aws, imgix, sanity) need a `path` URL prefix so the loader knows where to rewrite image src URLs. The check at config.ts:762-770 throws only when loader is neither 'default' nor 'custom' AND images.path still equals the default `/_next/image`. Without a custom path, the chosen external service cannot receive requests.

Source

Thrown at packages/next/src/server/config.ts:767

    if (images.domains) {
      if (!Array.isArray(images.domains)) {
        throw new Error(
          `Specified images.domains should be an Array received ${typeof images.domains}.\nSee more info here: https://nextjs.org/docs/messages/invalid-images-config`
        )
      }
    }

    if (!images.loader) {
      images.loader = 'default'
    }

    if (
      images.loader !== 'default' &&
      images.loader !== 'custom' &&
      images.path === imageConfigDefault.path
    ) {
      throw new Error(
        `Specified images.loader property (${images.loader}) also requires images.path property to be assigned to a URL prefix.\nSee more info here: https://nextjs.org/docs/api-reference/next/legacy/image#loader-configuration`
      )
    }

    if (
      images.path === imageConfigDefault.path &&
      result.basePath &&
      !pathHasPrefix(images.path, result.basePath)
    ) {
      images.path = `${result.basePath}${images.path}`
    }

    // Append trailing slash for non-default loaders and when trailingSlash is set
    if (
      images.path &&
      !images.path.endsWith('/') &&
      (images.loader !== 'default' || result.trailingSlash)
    ) {

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Add the loader-specific path, e.g. cloudinary: `images: { loader: 'cloudinary', path: 'https://res.cloudinary.com/<account>/image/upload/' }`.
  2. If you want a fully custom loader file, set `loader: 'custom'` plus `loaderFile`, which bypasses this check.
  3. If you want local optimization, set `loader: 'default'` and remove the path override.

Example fix

// before
module.exports = { images: { loader: 'cloudinary' } }
// after
module.exports = { images: { loader: 'cloudinary', path: 'https://res.cloudinary.com/my-account/image/upload/' } }
Defensive patterns

Strategy: validation

Validate before calling

const namedLoaders = ['cloudinary', 'akamai', 'aws', 'imgix', 'sanity'];
const { loader, path } = config.images ?? {};
if (loader && namedLoaders.includes(loader) && (path == null || path === '/_next/image')) {
  throw new Error(`loader ${loader} requires images.path`);
}

Type guard

function loaderHasRequiredPath(images: any): boolean {
  const named = ['cloudinary', 'akamai', 'aws', 'imgix', 'sanity'];
  return !(named.includes(images?.loader) && (images?.path == null || images.path === '/_next/image'));
}

Prevention

When it happens

Trigger: Setting `images: { loader: 'cloudinary' }` (or 'akamai', 'imgix', 'sanity') without a `path` property. The guard fires specifically when path is left at its default value.

Common situations: Following a partial tutorial that sets the loader but skips the path. Switching loaders and forgetting to update path. Assuming the default local `/_next/image` path works for an external loader.

Related errors


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