Your agent added a profile photo or a product card with <Image src="https://cdn.example.com/photos/1.jpg" ... /> from next/image. The page that used plain <img> worked, and now the image is gone: a broken icon in the browser, an error in the terminal, or a 400 on the image request in the Network tab. The URL opens fine when you paste it into a new tab.
The image is not missing. Next.js is refusing to optimize it, because nobody told Next.js that host is allowed.
Why this happens
The next/image docs say an absolute external URL in src “must be configured with remotePatterns” in next.config.js. Next.js fetches and resizes the image on your server, so it only does that for sources you listed. Anything that does not match the list gets refused: the docs say any other protocol, hostname, port, or unmatched path will respond with 400 Bad Request.
An agent writes the component first and the config second, or forgets the config entirely. It also tends to reach for the older domains option, which the docs mark as deprecated since Next.js 14 in favor of the stricter remotePatterns.
How to tell if this is your problem
- Open the failing image request in the browser Network tab. A
400on the/_next/imagerequest for an external URL points here. - Look at
next.config.js(ornext.config.mjsornext.config.ts). If there is noimages.remotePatternsentry for that host, this is the cause. - Compare the entry to the real URL. The match is on protocol, hostname, port, and path. A pattern for
https://example.com/account123/**does not allowhttps://example.com/other/photo.jpg, and it does not allow a URL with a query string unless you allow one.
The fix
Add the host to remotePatterns. The object form from the docs:
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.example.com',
port: '',
pathname: '/photos/**',
search: '',
},
],
},
}
A few details that matter:
- Subdomains: a wildcard such as
hostname: '**.example.com'allows subdomains likeimage.example.com. Per the docs,**works at the start of a hostname or the end of a path, not in the middle. - Query strings: the example above blocks them. Signed URLs and cache-busting
?v=2parameters need a matchingsearchvalue. The docs warn that leavingsearchout allows every query string, so prefer a specific value. - Restart the dev server after editing
next.config.js. Next.js reads it at startup. - Do not use
domainsfor new code. It is deprecated, cannot restrict protocol or path, and shares the safety problem the docs describe: most image servers host many tenants, so allowing the whole hostname lets others’ images through your optimizer.
If the image needs authentication, the docs say to use the unoptimized prop, which serves the URL as is instead of optimizing it.
How to avoid this next time
Add a rule to your agent’s instructions: “When you add an external image URL to next/image, also add a narrow remotePatterns entry in the same change. Never use domains, and never use hostname: '**'.” In review, check that every new external host in a src has a matching entry with a specific pathname.
Comments
Sign in to join the conversation.
No comments yet — be the first.