Skip to content

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.js

An 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. unoptimized on 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.

Related questions

Why not allow every hostname and move on?
Because the optimiser runs on your infrastructure and is billed to you. A wildcard means anyone who can get a URL into your content - a CMS field, a user avatar, a comment - can have your server fetch and resize an arbitrary image from an arbitrary host, as many times as they like.
Do I need this for images in /public?
No. Local images are served from your own origin and need no entry. This is only for images fetched from another host.