gohugoio/hugo · error

received invalid image dimensions: %dx

Error message

received invalid image dimensions: %dx%d stride %d

What it means

Thrown after a WASM-based AVIF decode when the returned Width, Height, or Stride from the avif codec is zero. The decoder reported success (dd.Execute returned no error) but the response params carry zero dimensions, which is unusable.

Solutions

  1. Re-export the AVIF from a known-good source (e.g., avifenc).
  2. Try decoding a different AVIF to isolate whether the issue is the file or the decoder.
  3. Check the libavif/aom/dav1d versions bundled with your Hugo release for known issues against this image.
  4. Re-encode the failing image with a standard AVIF tool and retry.
Defensive patterns

Strategy: validation

Validate before calling

// Before decode, confirm the file is non-empty and looks like an AVIF/HEIF
// box (ftyp brand).
hdr := make([]byte, 12)
if _, err := io.ReadFull(r, hdr); err != nil {
    return fmt.Errorf("cannot read AVIF header: %w", err)
}
if len(hdr) < 12 || string(hdr[8:12]) != "ftyp" {
    return fmt.Errorf("not an AVIF/HEIF file (missing ftyp box)")
}
// rewind r before handing to Decode

Prevention

When it happens

Trigger: An AVIF file is fed to AvifCodec.Decode; the WASM decoder executes successfully but the response's Width/Height/Stride fields are all 0. The check at avif.go:131 trips immediately, before any pixel buffer is constructed.

Common situations: Corrupt or truncated AVIF; an HEIF container the libavif decoder couldn't parse; an empty file; an unsupported AVIF profile (e.g., AVIF-J2K sequence); a bug or version mismatch in the bundled libavif WASM.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/c9132c201bb1fa23. Report an issue: GitHub.

Appendix: source

Thrown at internal/warpc/avif.go:132

			RequestKinds:  []string{MessageKindJSON, MessageKindBlob},
			ResponseKinds: []string{MessageKindJSON, MessageKindBlob},
		},

		Data: AvifInput{
			Source:      source,
			Destination: &destination,
			Options:     map[string]any{},
		},
	}

	out, err := dd.Execute(context.Background(), message)
	if err != nil {
		return nil, err
	}

	w, h, stride, depth := out.Data.Params.Width, out.Data.Params.Height, out.Data.Params.Stride, out.Data.Params.Depth
	if w == 0 || h == 0 || stride == 0 {
		return nil, fmt.Errorf("received invalid image dimensions: %dx%d stride %d", w, h, stride)
	}

	// For 10+ bit HDR images, the C code returns 16-bit RGBA data.
	isHDR := depth > 8

	// libavif returns 16-bit data in native (little-endian) byte order,
	// but Go's NRGBA64 expects big-endian. Swap bytes for HDR images.
	if isHDR {
		pix := destination.Bytes()
		for i := 0; i < len(pix); i += 2 {
			pix[i], pix[i+1] = pix[i+1], pix[i]
		}
	}

	if len(out.Data.Params.FrameDurations) > 0 {
		img := &AnimatedImage{
			frameDurations:          out.Data.Params.FrameDurations,
			loopCount:               avifLoopCountToGo(out.Data.Params.LoopCount),

View on GitHub (pinned to 52c9bd7908)