withastro/astro · error · AstroError

NoImageMetadata

NoImageMetadata

Error message

Could not process image metadata for `${url}`.

What it means

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.

Solutions

  1. Confirm the URL returns raw image bytes: `curl -sI <url>` and `curl -s <url> | file -`; fix the URL to point at the actual binary
  2. If the format is exotic (HEIC/AVIF variant), convert/host a jpg/png/webp rendition for the remote URL
  3. As a workaround, host/import the image locally so Astro reads metadata from the file instead of the stream

Example fix

```bash
# before
# https://cms.example.com/posts/1/cover actually returns HTML

# after: use the direct binary URL
# https://cms.example.com/media/posts/1/cover.png
```
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm the remote URL serves image bytes, not HTML
async function assertRemoteImageProbeable(url: string): Promise<void> {
  const res = await fetch(url, { redirect: 'follow' });
  const type = res.headers.get('content-type') ?? '';
  if (!type.startsWith('image/')) {
    throw new Error(`${url} is not served as an image (${type || 'unknown'})`);
  }
}

Try / catch

try {
  const size = await inferRemoteSize(url);
} catch (err) {
  if (err instanceof AstroError && err.code === 'NoImageMetadata') {
    // fall back to explicit dimensions supplied by content authors
    return { width: fallbackWidth, height: fallbackHeight, format: 'unknown' };
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/9efaf256d1373c74. Report an issue: GitHub.

Appendix: source

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

			accumulatedChunks = tmp;

			try {
				// Attempt to determine the size with each new chunk
				const dimensions = await imageMetadata(accumulatedChunks, url);

				if (dimensions) {
					await reader.cancel(); // stop stream as we have size now

					return dimensions;
				}
			} catch {
				// This catch block is specifically for `imageMetadata` errors
				// which might occur if the accumulated data isn't yet sufficient.
			}
		}
	}

	throw new AstroError({
		...AstroErrorData.NoImageMetadata,
		message: AstroErrorData.NoImageMetadata.message(url),
	});
}

View on GitHub (pinned to 52e6c34790)