{"record":{"id":"9efaf256d1373c74","repo":"withastro/astro","slug":"noimagemetadata-9efaf2","errorCode":"NoImageMetadata","errorMessage":"Could not process image metadata for `${url}`.","messagePattern":"Could not process image metadata for `(.+?)`\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/utils/remoteProbe.ts","lineNumber":132,"sourceCode":"\t\t\taccumulatedChunks = tmp;\n\n\t\t\ttry {\n\t\t\t\t// Attempt to determine the size with each new chunk\n\t\t\t\tconst dimensions = await imageMetadata(accumulatedChunks, url);\n\n\t\t\t\tif (dimensions) {\n\t\t\t\t\tawait reader.cancel(); // stop stream as we have size now\n\n\t\t\t\t\treturn dimensions;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// This catch block is specifically for `imageMetadata` errors\n\t\t\t\t// which might occur if the accumulated data isn't yet sufficient.\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new AstroError({\n\t\t...AstroErrorData.NoImageMetadata,\n\t\tmessage: AstroErrorData.NoImageMetadata.message(url),\n\t});\n}\n","sourceCodeStart":114,"sourceCodeEnd":137,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/assets/utils/remoteProbe.ts#L114-L137","documentation":"The final branch of `inferRemoteSize()`: the remote image was fetched and streamed chunk-by-chunk, but probing the accumulated bytes never produced dimensions — either the stream ended before a decodable header arrived, or the payload is not a recognizable image (e.g. HTML/JSON with an image URL). Astro throws NoImageMetadata for that URL.","triggerScenarios":"Remote URL serving HTML (error page, SPA shell) with 200 status; a format the probe cannot size from streamed bytes (some AVIF/HEIC variants, progressive encodings with late headers); server streaming the image after a large metadata blob; connection cut mid-transfer.","commonSituations":"CMS URL fields pointing at a page rather than the binary; content negotiation returning WebP/AVIF the probe partially supports; misconfigured CDN serving compressed/wrapped payloads; small images wrapped in multipart responses.","solutions":["Confirm the URL returns raw image bytes: `curl -sI <url>` and `curl -s <url> | file -`; fix the URL to point at the actual binary","If the format is exotic (HEIC/AVIF variant), convert/host a jpg/png/webp rendition for the remote URL","As a workaround, host/import the image locally so Astro reads metadata from the file instead of the stream"],"exampleFix":"```bash\n# before\n# https://cms.example.com/posts/1/cover actually returns HTML\n\n# after: use the direct binary URL\n# https://cms.example.com/media/posts/1/cover.png\n```","handlingStrategy":"try-catch","validationCode":"// confirm the remote URL serves image bytes, not HTML\nasync function assertRemoteImageProbeable(url: string): Promise<void> {\n  const res = await fetch(url, { redirect: 'follow' });\n  const type = res.headers.get('content-type') ?? '';\n  if (!type.startsWith('image/')) {\n    throw new Error(`${url} is not served as an image (${type || 'unknown'})`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const size = await inferRemoteSize(url);\n} catch (err) {\n  if (err instanceof AstroError && err.code === 'NoImageMetadata') {\n    // fall back to explicit dimensions supplied by content authors\n    return { width: fallbackWidth, height: fallbackHeight, format: 'unknown' };\n  }\n  throw err;\n}","preventionTips":["Require explicit width/height in CMS image fields when the host format is unusual","Point src at the direct binary URL, never a page/renderer URL"],"tags":["astro","images","remote","streaming","metadata"],"backgroundTag":"unreadable-image-metadata","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"}