withastro/astro · error · AstroError

RemoteImageNotAllowed

RemoteImageNotAllowed

Error message

Remote image ${url} is not allowed by your image configuration.

What it means

inferRemoteSize() with an imageConfig present: the request URL did not match image.domains or image.remotePatterns, so isRemoteAllowed() returned false and Astro refuses to fetch it (code RemoteImageNotAllowed). This is the allowlist gate that runs before any network request.

Source

Thrown at packages/astro/src/assets/utils/remoteProbe.ts:47

	const allowlistConfig = imageConfig
		? {
				domains: imageConfig.domains ?? [],
				remotePatterns: imageConfig.remotePatterns ?? [],
			}
		: undefined;

	if (!allowlistConfig) {
		const parsedUrl = new URL(url);
		if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
			throw new AstroError({
				...AstroErrorData.FailedToFetchRemoteImageDimensions,
				message: AstroErrorData.FailedToFetchRemoteImageDimensions.message(url),
			});
		}
	}

	if (allowlistConfig && !isRemoteAllowed(url, allowlistConfig)) {
		throw new AstroError({
			...AstroErrorData.RemoteImageNotAllowed,
			message: AstroErrorData.RemoteImageNotAllowed.message(url),
		});
	}

	// Start fetching the image with redirect validation
	let response: Response;
	try {
		response = await fetchWithRedirects({
			url,
			onMaxRedirectsExceeded: (u) =>
				new AstroError({
					...AstroErrorData.FailedToFetchRemoteImageDimensions,
					message: AstroErrorData.FailedToFetchRemoteImageDimensions.message(u),
				}),
			onMissingLocationHeader: (_status, u) =>
				new AstroError({
					...AstroErrorData.FailedToFetchRemoteImageDimensions,

View on GitHub (pinned to d081033d5f)

Solutions

  1. Add the host to `image.domains: ['cdn.example.com']` in astro.config.mjs.
  2. Or add a `image.remotePatterns` entry matching the URL (protocol, hostname, pathname wildcards).
  3. Remove `inferSize` from the <Image> if you do not need Astro to fetch dimensions (then the allowlist is not enforced for size inference).
  4. Verify the hostname spelling and that remotePatterns pathname pattern actually matches.

Example fix

// before
export default defineConfig({ image: { domains: [] } });

// after
export default defineConfig({
  image: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }] },
});
Defensive patterns

Strategy: validation

Validate before calling

import { isRemoteAllowed } from '@astrojs/internal-helpers/remote';
function isAllowedRemote(url: string, cfg: { domains: string[]; remotePatterns: any[] }) {
  return isRemoteAllowed(url, cfg);
}

Type guard

function matchesAllowlist(url: string, patterns: Array<{ hostname: string }>): boolean {
  try { return patterns.some(p => new URL(url).hostname === p.hostname || p.hostname.startsWith('*.')); }
  catch { return false; }
}

Prevention

When it happens

Trigger: Using <Image src="https://cdn.example.com/x.png" inferSize /> (or getImage with inferSize) where cdn.example.com is not listed in image.domains and not matched by image.remotePatterns in astro.config.

Common situations: New CDN/CMS domain not yet allowlisted; switched image host without updating config; remotePatterns regex/path does not match the actual URLs; using a staging domain not covered by the production allowlist.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/8ca20189ee37862f. Report an issue: GitHub.