vercel/next.js · error
Specified images.remotePatterns must have protocol "http" or
Error message
Specified images.remotePatterns must have protocol "http" or "https" received "${proto}". What it means
Each entry in `images.remotePatterns` may have `protocol` set to 'http', 'https', or omitted (undefined). The normalizer at config.ts:706-713 strips a trailing ':' then rejects any other value, because `new URL()` would accept arbitrary schemes (ftp:, file:, data:) that the image optimizer must not proxy. This is a security boundary check.
Source
Thrown at packages/next/src/server/config.ts:710
},
]
}
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,
port,
pathname,
search,
}
}
)
// static images are automatically prefixed with assetPrefix
// so we need to ensure _next/image allows downloading from
// this resource
if (config.assetPrefix?.startsWith('http')) {
try {View on GitHub (pinned to 0ae8c72462)
Solutions
- Set protocol to 'https' (preferred) or 'http': `{ protocol: 'https', hostname: 'cdn.example.com' }`.
- Omit protocol entirely if the default ('https' behavior) is acceptable.
- Double-check there is no trailing colon: use `'https'` not `'https:'`.
Example fix
// before
module.exports = { images: { remotePatterns: [{ protocol: 'ftp', hostname: 'cdn.example.com' }] } }
// after
module.exports = { images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }] } } Defensive patterns
Strategy: validation
Validate before calling
const allowed = ['http', 'https', undefined];
for (const p of config.images?.remotePatterns ?? []) {
const proto = (p.protocol ?? '').replace(/:$/, '');
if (proto !== '' && !['http', 'https'].includes(proto)) throw new Error('invalid protocol: ' + proto);
} Type guard
function isValidProtocol(p: unknown): p is 'http' | 'https' | undefined {
return p === undefined || p === 'http' || p === 'https' || p === 'http:' || p === 'https:';
} Prevention
- Only ever set protocol to 'https' (preferred) or 'http'.
- Never copy a scheme like 'ftp://' from an asset link into a remotePattern.
When it happens
Trigger: Supplying `protocol: 'ftp'`, `protocol: 'file'`, `protocol: 'data'`, or a malformed value like `protocol: 'http//'` in a remotePattern.
Common situations: Copy-pasting a URL scheme from an asset link that isn't HTTP(S). Using an older config that allowed looser values. Typos such as `protcol` leaving protocol derived from another source.
Related errors
- Specified images.remotePatterns should be an Array received
- 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/af1839cda3c5f91e.
Report an issue: GitHub.