withastro/astro · error · AstroError

NoImageMetadata

NoImageMetadata

Error message

Could not process image metadata for `${transform.src}`.

What it means

Inside the Sharp service's `transform`, Astro probes the input buffer to learn its real format. If `sharp`'s metadata returns no recognizable format for the bytes (bufferFormat is undefined), Astro refuses to process the file and throws NoImageMetadata rather than guessing. It means the payload is corrupt, truncated, or a format the metadata probe cannot identify.

Solutions

  1. Open the file locally in an image viewer to confirm it is a valid, complete image; re-export it from an editor
  2. Verify the bytes match the extension (e.g. `file hero.png`); re-download or re-commit the real image
  3. If the file is a valid but unusual format, convert it to a supported one (png/jpeg/webp/avif/gif) before handing it to Astro

Example fix

```bash
# before: file is actually HTML saved as .png
file public/hero.png
# public/hero.png: HTML document text

# after: replace with the real image
file public/hero.png
# public/hero.png: PNG image data, 1200 x 630
```
Defensive patterns

Strategy: validation

Validate before calling

import { lookup } from 'image-size'; // or sniff magic bytes

async function assertProbeable(buffer: Uint8Array, name: string) {
  try {
    const dim = lookup(buffer);
    if (!dim.width || !dim.height || !dim.type) throw new Error('no dims');
  } catch {
    throw new Error(`${name} is not a recognizable image — fix or exclude it`);
  }
}

Try / catch

try {
  const result = await service.transform(inputBuffer, transform);
} catch (err) {
  if (err instanceof AstroError && err.code === 'NoImageMetadata') {
    // copy the original through instead of transforming
    return { data: inputBuffer, format: transform.format };
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a truncated/corrupted image to `getImage()`; a file with an image extension whose actual bytes are something else (HTML error page saved as .png); an exotic format sharp cannot identify; zero-byte images; requesting non-svg processing of an unsupported binary.

Common situations: Images downloaded from a URL that actually returned HTML/JSON; files mangled by a bad git-lfs checkout or interrupted upload; CI artifacts corrupted by transfer; HEIC or ICO files renamed to .jpg.

Related errors


AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18). Data as JSON: /api/errors/7f8d02fe728a8d44. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/assets/services/sharp.ts:171

		const bufferFormat = detector(inputBuffer);
		// Resolve the output format from the buffer when validateOptions deferred (ambiguous remote URL hit SSR, manually formed URLs etc)
		const outputFormat = transform.format ?? resolveDefaultOutputFormat(bufferFormat);

		// TODO: Sharp has some support for SVGs, we could probably support this once Sharp is the default and only service.
		if (outputFormat === 'svg') {
			if (bufferFormat && bufferFormat !== 'svg') {
				logger.warn(
					`Astro expected an SVG for "${transform.src}" but the source is ${bufferFormat}. Passing it through as ${bufferFormat} instead.`,
				);
				return { data: inputBuffer, format: bufferFormat as ImageOutputFormat };
			}
			return { data: inputBuffer, format: 'svg' };
		}

		// If we couldn't figure out the format, it's probably something weird we shouldn't try to process.
		if (!bufferFormat) {
			throw new AstroError({
				...AstroErrorData.NoImageMetadata,
				message: AstroErrorData.NoImageMetadata.message(transform.src),
			});
		}

		if (bufferFormat === 'svg' && !config.dangerouslyProcessSVG) {
			throw new AstroError({
				...AstroErrorData.UnsupportedImageFormat,
				message: `SVG image processing is disabled, but the source for "${transform.src}" is an SVG. Pass it through unchanged by setting \`format="svg"\` on the component, or set \`image.dangerouslyProcessSVG: true\` to rasterize SVG sources.`,
			});
		}

		const result = sharp(inputBuffer, {
			failOn: 'none',
			pages: -1,
			limitInputPixels: config.service.config.limitInputPixels,
		});

View on GitHub (pinned to e294953aa8)