withastro/astro · warning
⚠️ Astro expected an SVG for "${transform.src}" but the sou
Error message
⚠️ Astro expected an SVG for "${transform.src}" but the source is ${bufferFormat}. Passing it through as ${bufferFormat} instead. What it means
Astro's Sharp image service cannot encode SVG, so when the resolved output format for a transform is 'svg' but byte-level format detection reports a different input format, it warns and returns the original buffer unchanged, relabeled with the detected format. The detector sniffs magic bytes, not the file extension, so this fires when the source is not actually an SVG despite its name or the requested format.
Source
Thrown at packages/astro/src/assets/services/sharp.ts:161
validateOptions: baseService.validateOptions,
getURL: baseService.getURL,
parseURL: baseService.parseURL,
getHTMLAttributes: baseService.getHTMLAttributes,
getSrcSet: baseService.getSrcSet,
getRemoteSize: baseService.getRemoteSize,
async transform(inputBuffer, transformOptions, config) {
if (!sharp) sharp = await loadSharp();
const transform: BaseServiceTransform = transformOptions as BaseServiceTransform;
const kernel = config.service.config.kernel;
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,View on GitHub (pinned to 52e6c34790)
Solutions
- Convert the source file to a real vector SVG so its bytes match the .svg extension
- Remove the format="svg" prop and let Astro choose the output format (e.g. webp)
- Rename the source to its true extension (.png/.jpg) and update imports/references
- If serving the raster as-is is acceptable, no action needed: the image still passes through, just unoptimized under its real format
Example fix
// before: logo.svg actually contains PNG bytes
<Image src={logo} format="svg" alt="Logo" />
// after: let Astro optimize into a supported raster format
<Image src={logo} format="webp" alt="Logo" /> Defensive patterns
Strategy: validation
Validate before calling
// Before passing an .svg asset with format="svg", verify the bytes are really SVG:
import { readFile } from 'node:fs/promises';
function isSvgBuffer(buf: Uint8Array): boolean {
const head = new TextDecoder().decode(buf.slice(0, 256)).trimStart().toLowerCase();
return head.startsWith('<?xml') || head.startsWith('<svg');
}
const bytes = await readFile('src/assets/logo.svg');
if (!isSvgBuffer(bytes)) throw new Error('logo.svg contains raster data — convert it or drop format="svg"'); Type guard
type SharpEncodableFormat = 'webp' | 'png' | 'jpeg' | 'avif' | 'gif';
const SHARP_ENCODABLE = new Set(['webp', 'png', 'jpeg', 'avif', 'gif']);
function isSharpEncodable(f: string): f is SharpEncodableFormat {
return SHARP_ENCODABLE.has(f);
} Prevention
- Never request format="svg" from the optimizer — Sharp cannot encode SVG
- Treat file extensions as metadata, not truth; sniff bytes when sources are untrusted
- Add a CI check that every committed .svg starts with '<svg' or '<?xml'
When it happens
Trigger: Passing format="svg" on <Image>/<Picture> or in getImage()/image() options while the source's real bytes are PNG/JPEG/WebP; or hitting the deferred-format path (ambiguous remote URL resolved during SSR) where resolveDefaultOutputFormat() returns 'svg' for a non-SVG buffer. Classic trigger: a file with an .svg extension that actually contains raster data.
Common situations: A PNG renamed to .svg without conversion; design tools exporting 'SVG' files that embed raster images; CDN/remote URLs serving WebP or JPEG bytes under an .svg URL; copy-pasted format="svg" props from snippets.
Related errors
- UnsupportedImageFormat
- ⚠️ Astro could not optimize image "${transform.src}". Sharp
- UnsupportedImageConversion
- MissingSharp
- NoImageMetadata
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/8695e8fdb82a9933.
Report an issue: GitHub.