vercel/next.js · error
Specified images.remotePatterns should be an Array received
Error message
Specified images.remotePatterns should be an Array received ${typeof images.remotePatterns}.
See more info here: https://nextjs.org/docs/messages/invalid-images-config What it means
`images.remotePatterns` defines remote hosts _next/image is allowed to optimize and must be an array of pattern objects. The check at config.ts:696-701 rejects truthy non-arrays because the code immediately calls `.map()` over entries to normalize protocol/host/port. An unset value is fine (no remote hosts); only a wrong-typed value throws.
Source
Thrown at packages/next/src/server/config.ts:698
// static import images are automatically allowed
images.localPatterns.push({
pathname: '/_next/static/immutable/media/**',
search: '',
})
}
} else {
// All paths are not allowed for a search query by default.
images.localPatterns = [
{
pathname: '**',
search: '',
},
]
}
if (images.remotePatterns) {
if (!Array.isArray(images.remotePatterns)) {
throw new Error(
`Specified images.remotePatterns should be an Array received ${typeof images.remotePatterns}.\nSee more info here: https://nextjs.org/docs/messages/invalid-images-config`
)
}
// We must convert URL to RemotePattern since URL has a colon in the protocol
// and also has additional properties we want to filter out. Also, new URL()
// accepts any protocol so we need manual validation here.
images.remotePatterns = images.remotePatterns.map(
({ protocol, hostname, port, pathname, search }) => {
const proto = protocol?.replace(/:$/, '')
if (!['http', 'https', undefined].includes(proto)) {
throw new Error(
`Specified images.remotePatterns must have protocol "http" or "https" received "${proto}".`
)
}
return {
protocol: proto as 'http' | 'https' | undefined,
hostname,View on GitHub (pinned to 0ae8c72462)
Solutions
- Wrap remote patterns in an array: `remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }]`.
- Use `domains: ['cdn.example.com']` only if you need the legacy simpler form.
- Drop the key entirely to disable remote optimization.
Example fix
// before
module.exports = { images: { remotePatterns: { hostname: 'cdn.example.com' } } }
// after
module.exports = { images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }] } } Defensive patterns
Strategy: type-guard
Validate before calling
const rp = config.images?.remotePatterns;
if (rp != null && !Array.isArray(rp)) throw new Error('images.remotePatterns must be an array');
for (const p of rp ?? []) { if (typeof p.hostname !== 'string') throw new Error('each remotePattern needs a hostname string'); } Type guard
type RemotePattern = { protocol?: 'http' | 'https'; hostname: string; port?: string; pathname?: string; search?: string };
function isRemotePatternsArray(v: unknown): v is RemotePattern[] {
return Array.isArray(v) && v.every((p) => p && typeof (p as any).hostname === 'string');
} Prevention
- Distinguish remotePatterns (array of objects) from the legacy domains (array of strings).
- Wrap example objects in `[ ]` when copying from docs.
When it happens
Trigger: Setting `images: { remotePatterns: { hostname: 'cdn.com' } }` (single object) or `remotePatterns: 'cdn.com'` (string).
Common situations: Confusing remotePatterns (array of structured objects) with the deprecated `domains` (array of strings). Copying a single example object from docs without wrapping it in `[ ]`.
Related errors
- Specified images.remotePatterns must have protocol "http" or
- Specified images should be an object received ${typeof image
- Specified images.localPatterns should be an Array received $
- Invalid assetPrefix provided. Original error: ${error}
- Specified images.domains should be an Array received ${typeo
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/26f1eee95c606131.
Report an issue: GitHub.