{"record":{"id":"8ca20189ee37862f","repo":"withastro/astro","slug":"remoteimagenotallowed-8ca201","errorCode":"RemoteImageNotAllowed","errorMessage":"Remote image ${url} is not allowed by your image configuration.","messagePattern":"Remote image (.+?) is not allowed by your image configuration\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/utils/remoteProbe.ts","lineNumber":47,"sourceCode":"\tconst allowlistConfig = imageConfig\n\t\t? {\n\t\t\t\tdomains: imageConfig.domains ?? [],\n\t\t\t\tremotePatterns: imageConfig.remotePatterns ?? [],\n\t\t\t}\n\t\t: undefined;\n\n\tif (!allowlistConfig) {\n\t\tconst parsedUrl = new URL(url);\n\t\tif (!['http:', 'https:'].includes(parsedUrl.protocol)) {\n\t\t\tthrow new AstroError({\n\t\t\t\t...AstroErrorData.FailedToFetchRemoteImageDimensions,\n\t\t\t\tmessage: AstroErrorData.FailedToFetchRemoteImageDimensions.message(url),\n\t\t\t});\n\t\t}\n\t}\n\n\tif (allowlistConfig && !isRemoteAllowed(url, allowlistConfig)) {\n\t\tthrow new AstroError({\n\t\t\t...AstroErrorData.RemoteImageNotAllowed,\n\t\t\tmessage: AstroErrorData.RemoteImageNotAllowed.message(url),\n\t\t});\n\t}\n\n\t// Start fetching the image with redirect validation\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRedirects({\n\t\t\turl,\n\t\t\tonMaxRedirectsExceeded: (u) =>\n\t\t\t\tnew AstroError({\n\t\t\t\t\t...AstroErrorData.FailedToFetchRemoteImageDimensions,\n\t\t\t\t\tmessage: AstroErrorData.FailedToFetchRemoteImageDimensions.message(u),\n\t\t\t\t}),\n\t\t\tonMissingLocationHeader: (_status, u) =>\n\t\t\t\tnew AstroError({\n\t\t\t\t\t...AstroErrorData.FailedToFetchRemoteImageDimensions,","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/assets/utils/remoteProbe.ts#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the host to `image.domains: ['cdn.example.com']` in astro.config.mjs.","Or add a `image.remotePatterns` entry matching the URL (protocol, hostname, pathname wildcards).","Remove `inferSize` from the <Image> if you do not need Astro to fetch dimensions (then the allowlist is not enforced for size inference).","Verify the hostname spelling and that remotePatterns pathname pattern actually matches."],"exampleFix":"// before\nexport default defineConfig({ image: { domains: [] } });\n\n// after\nexport default defineConfig({\n  image: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }] },\n});","handlingStrategy":"validation","validationCode":"import { isRemoteAllowed } from '@astrojs/internal-helpers/remote';\nfunction isAllowedRemote(url: string, cfg: { domains: string[]; remotePatterns: any[] }) {\n  return isRemoteAllowed(url, cfg);\n}","typeGuard":"function matchesAllowlist(url: string, patterns: Array<{ hostname: string }>): boolean {\n  try { return patterns.some(p => new URL(url).hostname === p.hostname || p.hostname.startsWith('*.')); }\n  catch { return false; }\n}","tryCatchPattern":null,"preventionTips":["Keep image.domains/remotePatterns in sync with your CMS/CDN hosts.","Add staging hosts to remotePatterns alongside production.","Document new image sources in the config when onboarding a CDN."],"tags":["assets","remote-images","configuration","security"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}