{"record":{"id":"9ef9ffa9d0a08d1c","repo":"withastro/astro","slug":"failedtofetchremoteimagedimensions","errorCode":"FailedToFetchRemoteImageDimensions","errorMessage":"Failed to get the dimensions for ${url}.","messagePattern":"Failed to get the dimensions for (.+?)\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/utils/remoteProbe.ts","lineNumber":23,"sourceCode":"import { imageMetadata } from './metadata.js';\nimport { fetchWithRedirects } from './redirectValidation.js';\n\ntype RemoteImageConfig = Pick<AstroConfig['image'], 'domains' | 'remotePatterns'>;\n\n/**\n * Infers the dimensions of a remote image by streaming its data and analyzing it progressively until sufficient metadata is available.\n *\n * @param {string} url - The URL of the remote image from which to infer size metadata.\n * @param {RemoteImageConfig} [imageConfig] - Optional image config used to validate remote allowlists.\n * @return {Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>} Returns a promise that resolves to an object containing the image dimensions metadata excluding `src` and `fsPath`.\n * @throws {AstroError} Thrown when the fetching fails or metadata cannot be extracted.\n */\nexport async function inferRemoteSize(\n\turl: string,\n\timageConfig?: RemoteImageConfig,\n): Promise<Omit<ImageMetadata, 'src' | 'fsPath'>> {\n\tif (!URL.canParse(url)) {\n\t\tthrow new AstroError({\n\t\t\t...AstroErrorData.FailedToFetchRemoteImageDimensions,\n\t\t\tmessage: AstroErrorData.FailedToFetchRemoteImageDimensions.message(url),\n\t\t});\n\t}\n\n\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),","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/assets/utils/remoteProbe.ts#L5-L41","documentation":"`inferRemoteSize()` streams a remote image to read its dimensions (used by `getImage`/`<Image>` for remote sources without explicit width/height). Before anything else it validates the URL with `URL.canParse`; a string that is not a parseable URL (missing protocol, spaces, malformed) fails immediately with FailedToFetchRemoteImageDimensions.","triggerScenarios":"`<Image src=\"example.com/image.png\" />` (no https:// prefix); a src with unencoded spaces or invalid characters; template-built URLs that end up empty or malformed; passing a relative path to the remote-image path.","commonSituations":"Forgetting the protocol when moving from local `/img.png` to remote images; URLs copy-pasted with smart quotes or trailing punctuation; CMS fields that return null rendered as the string 'null'.","solutions":["Use a fully-qualified URL including protocol: `https://example.com/image.png`","Encode dynamic parts: `new URL(path, base).href` or `encodeURIComponent` on segments before passing as src","If the image is local, import it or use a root-relative path instead of the remote path"],"exampleFix":"<!-- before -->\n<Image src=\"cdn.example.com/hero.png\" alt=\"Hero\" />\n\n<!-- after -->\n<Image src=\"https://cdn.example.com/hero.png\" alt=\"Hero\" />","handlingStrategy":"validation","validationCode":"// validate before passing any remote src to <Image>/getImage\nfunction assertValidRemoteUrl(src: string): void {\n  if (!URL.canParse(src)) {\n    throw new Error(`Invalid image URL: ${src} (include the protocol, e.g. https://)`);\n  }\n}","typeGuard":"function isParseableRemoteUrl(src: string): src is `https://${string}` {\n  return URL.canParse(src) && src.startsWith('https://');\n}","tryCatchPattern":"try {\n  const size = await inferRemoteSize(url);\n} catch (err) {\n  if (err instanceof AstroError && err.code === 'FailedToFetchRemoteImageDimensions') {\n    // surface the raw URL to content authors for manual fixing\n    throw new Error(`Remote image URL is invalid or unreachable: ${url}`);\n  }\n  throw err;\n}","preventionTips":["Always build remote srcs with `new URL(path, base).href`","Validate CMS-supplied image URLs (canParse + https) before rendering"],"tags":["astro","images","remote","url-validation"],"backgroundTag":"remote-image-fetch-failed","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}