Next.js error
Invalid src prop - hostname Is Not Configured Under images
The error
Error: Invalid src prop (https://cdn.example.com/photo.jpg) on `next/image`, hostname "cdn.example.com" is not configured under images in your next.config.jsAn allowlist you have not filled in, and it is a deliberate one - the optimiser will resize anything you point it at, including things you did not mean to pay for.
next/image does not simply render a URL. It fetches the file, resizes it,
converts the format and caches the result - on your infrastructure. The
allowlist exists because that is a service you are paying for, and an
unrestricted optimiser is an open proxy with a bill attached.
The error is that allowlist doing its job.
The fix
Add the host to remotePatterns in next.config.ts:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.example.com',
pathname: '/uploads/**',
},
],
},
};
export default nextConfig;Restart the dev server - next.config.ts is read at startup, so a change to it
does not hot-reload, and this is the reason most "I added it and it still
fails" reports resolve themselves.
Three things worth getting right while you are in there:
Be as specific as the source allows. hostname accepts one leading
wildcard (**.example.com), and pathname narrows it further. A CMS that
serves everything from /uploads/ should be allowed /uploads/**, not /**.
One entry per host, not per image. A common mistake is adding the hostname and then discovering a second bucket or a second region, and ending up with six near-identical entries. Group them with the wildcard instead.
domains is the old key. If you are reading an answer that uses
images.domains, it predates remotePatterns and is deprecated - it had no
path or protocol matching, which is exactly the control you want here.
When the host is not yours
If the URL comes from user input or a third-party service you do not control, allowlisting it is the wrong shape of fix. You are inviting an arbitrary host into your optimiser's fetch path. Two better options:
- Proxy it through your own storage. Upload on receipt, serve from a host you own, allowlist that one host.
- Skip optimisation for that case.
unoptimizedon the single image, or a plain<img>, means Next.js never fetches it. You lose the resizing for that image and you keep the control.
What looks like a fix and is not
hostname: '**'. Allowed by the config, and it turns the optimiser into a
general-purpose image proxy for the whole internet, billed to you and cached
on your infrastructure. If you have this in a repository right now it is worth
changing today.
unoptimized: true globally. The error disappears because next/image
stops optimising anything. So do the format conversion, the responsive
srcset and the resizing - and the LCP work you were relying on it for.
next/image will not fix your LCP on its own, but
switching it off entirely gives back the part that does help.
Swapping to <img> everywhere. Same trade, plus you lose the automatic
width/height attributes, which is
one of the ordinary ways to reintroduce layout
shift.
The check worth running once
Every remote host your application renders images from should be in that list deliberately - and the list should be shorter than you expect. In most codebases we read, it contains at least one host that was added for a feature that no longer exists, and at least one wildcard nobody remembers approving.
