withastro/astro · error · AstroError

NoImageMetadata

NoImageMetadata

Error message

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

What it means

Thrown by the sharp service when it cannot determine the input image's format from the buffer (bufferFormat is falsy). Sharp uses a sniff to detect format; if no format is detected the source is treated as unprocessable and NoImageMetadata is thrown with transform.src in the message. This is separate from the SVG path which is handled first.

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') {
				console.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 d081033d5f)

Solutions

  1. Verify the source file is a complete, valid image of a supported format.
  2. Re-download/replace the corrupt or truncated source.
  3. Confirm the URL actually serves image bytes (not an error page) — check content-type.
  4. If the source is SVG, set format: 'svg' to take the SVG pass-through path.
  5. Open the file in an image viewer to confirm it is not corrupt.

Example fix

// before - remote URL returns an HTML 404 page saved as .png
getImage({ src: 'https://cdn/missing.png', width: 100, height: 100 })

// after - point at a real, valid image
getImage({ src: 'https://cdn/real.png', width: 100, height: 100 })
Defensive patterns

Strategy: validation

Validate before calling

import { fileTypeFromBuffer } from 'file-type';
async function hasDetectableFormat(buf: Buffer): Promise<boolean> {
  try { return !!(await fileTypeFromBuffer(buf)); } catch { return false; }
}

Try / catch

try { await service.transform(inputBuffer, transform); }
catch (e) {
  if (e instanceof AstroError && e.code === 'NoImageMetadata') {
    // source is corrupt/non-image; replace it before retrying
  }
}

Prevention

When it happens

Trigger: Passing a transform to sharp whose inputBuffer has no detectable format — e.g. a corrupt/truncated file, a non-image binary, an empty buffer, or a format sharp's sniffer does not recognize. Only reached when outputFormat is not 'svg' and bufferFormat is falsy.

Common situations: A downloaded/cached image that is truncated, a file that is not actually an image (e.g. an HTML error page saved as .png), a zero-byte file, or an unsupported exotic format passed to sharp.

Related errors


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