withastro/astro · error · AstroError

UnsupportedImageFormat

UnsupportedImageFormat

Error 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.

What it means

Thrown by the sharp service when the input buffer is detected as SVG, outputFormat is not 'svg', and config.dangerouslyProcessSVG is falsy. Astro does not rasterize SVGs through sharp by default for safety; it requires an explicit opt-in. The message tells the user to either pass format='svg' (to pass it through unchanged) or set image.dangerouslyProcessSVG: true to rasterize.

Source

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

			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,
		});

		// always call rotate to adjust for EXIF data orientation
		result.rotate();

		if (transform.width && transform.height) {
			const fit: keyof FitEnum | undefined = transform.fit
				? (fitMap[transform.fit] ?? 'inside')
				: undefined;

View on GitHub (pinned to d081033d5f)

Solutions

  1. Set format: 'svg' on the component/getImage to pass the SVG through unchanged.
  2. Or enable rasterization explicitly: image: { dangerouslyProcessSVG: true } in astro.config.
  3. Pre-convert the SVG to a raster format with an external tool if occasional raster output is needed.
  4. Keep SVGs as SVG unless rasterization is genuinely required.

Example fix

// before
<Image src={logoSvg} format='png' />

// after
<Image src={logoSvg} format='svg' />
Defensive patterns

Strategy: validation

Validate before calling

function svgOutputSafe(srcFormat: string, outputFormat: string | undefined, allowDangerous: boolean): boolean {
  if (srcFormat === 'svg') return outputFormat === 'svg' || !!allowDangerous;
  return true;
}

Prevention

When it happens

Trigger: Passing an SVG source to getImage/<Image> with a raster output format (e.g. format: 'png') while image.dangerouslyProcessSVG is unset/false. bufferFormat === 'svg' triggers the guard; outputFormat being anything other than 'svg' was already handled earlier.

Common situations: Author imports an SVG and requests rasterization (png/webp) without opting in, or a shared component forces a raster format onto an SVG import. Rasterizing SVG via sharp can be a security/DoS surface, hence the opt-in.

Related errors


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