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
- Add the loader-specific path, e.g. cloudinary: `images: { loader: 'cloudinary', path: 'https://res.cloudinary.com/<account>/image/upload/' }`.
- If you want a fully custom loader file, set `loader: 'custom'` plus `loaderFile`, which bypasses this check.
- 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
- Whenever you set a named loader, immediately also set the corresponding path.
- Keep a lookup table of loader -> default path template in your config generator.
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
- Specified images.loader property (${images.loader}) cannot b
- Specified images should be an object received ${typeof image
- Specified images.localPatterns should be an Array received $
- Specified images.remotePatterns should be an Array received
- Specified images.remotePatterns must have protocol "http" or
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/ace3eed1ad0c2418.
Report an issue: GitHub.