Next.js

Fix next/image Hostname Not Configured in Next.js

next/image strictly allow-lists remote hosts. The fix is images.remotePatterns in next.config — matched exactly on protocol, hostname, port, and pathname. Get one wrong (http vs https, a subdomain, a missing port) and it still blocks.

Mahdi Ben RhoumaMahdi Ben Rhouma
Updated
7 min read

You drop a remote image into <Image> and the page explodes:

text
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

next/image strictly allow-lists the hosts it will optimize — remote image servers are often shared between tenants, so allow-listing protects your optimizer from being pointed at arbitrary URLs. The fix is one config block, but the matching is unforgiving.

The fix: images.remotePatterns#

Add the host with explicit fields:

js
// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'cdn.example.com',
        port: '',
        pathname: '/photos/**',
      },
    ],
  },
}

Then restart the dev server — next.config is read once at startup and is not hot-reloaded.

Why it still blocks after you 'added the domain'

Every part of the URL is matched exactly and case-sensitively:

  • Protocol — http ≠ https
  • Hostname — example.com ≠ www.example.com ≠ assets.example.com
  • Port — if present (:3000 in dev), it must be included
  • Pathname — must be covered by the glob; /images/ does not match /images/photo.jpg, you need /images/**

Wildcard rules#

* and ** behave differently — and ** only works at the edges:

  • * — a single path segment, or a single subdomain
  • ** — any number of trailing path segments, or any number of leading subdomains
js
// allows image.example.com, cdn.example.com, etc.
{ protocol: 'https', hostname: '**.example.com' }

Omitting protocol, port, pathname, or search makes them wildcard — the docs explicitly call this not recommended for security. In particular, omitting search allows all query strings.

Newer shorthand (Next 15.3.0+)

Since v15.3.0 you can pass URL objects: remotePatterns: [new URL('https://cdn.example.com/photos/**')]. On older versions, use the object form.

Why not images.domains?#

You'll see older answers using images.domains: ['cdn.example.com']. It still works, but the official docs mark it deprecated since Next.js 14 "in favor of strict remotePatterns in order to protect your application from malicious users." domains is a flat hostname list with no wildcard, protocol, port, or pathname control. Migrate:

Don't
images: { domains: ['cdn.example.com'] } // deprecated since Next 14, no protocol/port/path control
Do
images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com', pathname: '/photos/**' }] }

Escape hatches (and their cost)#

  • unoptimized — a prop (or images.unoptimized: true globally) that skips the optimization pipeline and bypasses the allow-list. Right for tiny images, SVGs, or images that need auth headers (the optimizer doesn't forward them). Tradeoff: no resizing, no format conversion, no optimized caching.
  • loader / loaderFile — offload optimization to Cloudinary, Imgix, Supabase, etc. via a function ({ src, width, quality }) => string. Tradeoff: a custom loaderFile requires Client Components and hands optimization to a third party.
When this won't work
  • The image needs authentication — the built-in optimizer doesn't forward headers; use unoptimized or a custom loader.
  • You're on Next.js before 12.3 — remotePatterns isn't stable there; the search prop needs 14.2.14+, and URL-object shorthand needs 15.3.0+.

Official references: next/image "Un-configured Host" error, Image component / remotePatterns, images config.

Fixed remotePatterns, image still blocked: check the CSP img-src directive#

images.remotePatterns only controls one gate: whether Next's own image-optimization pipeline is willing to fetch and resize a given remote host. It has nothing to do with a second, independent gate a lot of production apps also enforce: a Content-Security-Policy response header with an img-src directive. If that header lists specific hosts (or omits img-src and falls back to a strict default-src), the browser itself will refuse to load an image from any host not on that list — regardless of what remotePatterns says, and regardless of whether the optimizer successfully processed it server-side.

The symptom looks confusingly similar to the original bug: a broken image, sometimes with no visible error in the Next.js server logs at all, because the request never even reaches your server — the browser blocks it client-side. The real signal is in the browser DevTools console, not the terminal: a CSP violation naming img-src, not the next/image "hostname is not configured" error this page opened with.

The fix is adding the same host to the CSP header's img-src list, alongside remotePatterns — the two lists are unrelated and both need the host added independently. For the full checklist of security headers a Next.js + Supabase app typically ships, including where CSP directives are usually defined and how to test they don't silently block Supabase Storage URLs or other remote assets, see Next.js + Supabase Security Best Practices (2026).

When remotePatterns is correct but nothing gets optimized at all#

A different failure mode looks identical from the config file but has nothing to do with hostnames: on a static export build (output: 'export' in next.config), Next does not run its built-in, server-side image optimizer at all — there is no server process left to run it against. The official Next.js docs call this out directly as a limitation of static exports, and several non-Vercel hosting targets that adapt Next.js output for their own runtime have the same limitation for the same reason — no long-running Node process available to do on-demand resizing and format conversion.

In that situation, images.remotePatterns can be configured perfectly and the error from earlier in this page will be gone, but images either fail to render at all or silently skip optimization (served at original size and format) rather than being resized. The fix is not more allow-listing — it's telling Next not to expect an optimizer to be there: set images.unoptimized: true globally, or point images.loader / images.loaderFile at a third-party image CDN (Cloudinary, Imgix, Supabase's own transform endpoint) that does the resizing instead. This is the same unoptimized/loader trade-off already covered above for auth-gated images, just triggered by the deployment target instead of by the image needing headers the optimizer can't forward. A missing optimizer server also changes how layout-shift bugs show up on the same images — see Fix Cumulative Layout Shift from next/image for the sizing attributes that matter once resizing isn't happening automatically.

Further reading: How to set the next/image component to 100% height, Next.js Images Not Loading from public/static Folder: Fix. Also see How to implement LCP end to end.

Frequently Asked Questions

|

Have more questions? Contact us

Still stuck? Paste your error.

Paste the error message or stack trace — we check it against every fix and tool on the site.

Matching happens in your browser. When you search, a cleaned error signature is sent so we can spot errors we do not cover yet — never the raw text, your IP address or your e-mail. Do not paste passwords or keys. Details

Written by

Mahdi Ben Rhouma
Mahdi Ben Rhouma

Full-Stack Dev — Next.js & Supabase

Solo developer building SaaS products with Next.js and Supabase. Writing about production patterns the official docs skip.

Remote

One email a month — the latest explained errors

What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.