gohugoio/hugo · error
failed to decode image: %s
Error message
failed to decode image: %s
What it means
Thrown by the mask filter's Draw when the mask image source cannot be decoded (mask.go:19-22). DecodeImage returns an error (corrupt file, unsupported format, unreadable resource) and the filter panics, propagating the underlying decode error message.
Source
Thrown at resources/images/mask.go:21
import (
"fmt"
"image"
"image/color"
"image/draw"
"github.com/gohugoio/gift"
)
// maskFilter applies a mask image to a base image.
type maskFilter struct {
mask ImageSource
}
// Draw applies the mask to the base image.
func (f maskFilter) Draw(dst draw.Image, baseImage image.Image, options *gift.Options) {
maskImage, err := f.mask.DecodeImage()
if err != nil {
panic(fmt.Sprintf("failed to decode image: %s", err))
}
// Ensure the mask is the same size as the base image
baseBounds := baseImage.Bounds()
maskBounds := maskImage.Bounds()
// Resize mask to match base image size if necessary
if maskBounds.Dx() != baseBounds.Dx() || maskBounds.Dy() != baseBounds.Dy() {
g := gift.New(gift.Resize(baseBounds.Dx(), baseBounds.Dy(), gift.LanczosResampling))
resizedMask := image.NewRGBA(g.Bounds(maskImage.Bounds()))
g.Draw(resizedMask, maskImage)
maskImage = resizedMask
}
// Use gift to convert the resized mask to grayscale
g := gift.New(gift.Grayscale())
grayscaleMask := image.NewGray(g.Bounds(maskImage.Bounds()))
g.Draw(grayscaleMask, maskImage)View on GitHub (pinned to 52c9bd7908)
Solutions
- Verify the mask resource is a decodable image (PNG/JPEG/GIF/WebP/BMP/TIFF).
- Check the resource is non-nil and readable before using it as a mask.
- Re-download or replace corrupt mask files.
Example fix
// before
{{ $mask := resources.Get "icons/mask.svg" }}
{{ $filters = $filters | append (images.Mask $mask) }}
// after
{{ $mask := resources.Get "icons/mask.png" }}
{{ $filters = $filters | append (images.Mask $mask) }} Defensive patterns
Strategy: validation
Validate before calling
{{ with $mask }}
{{ if reflect.IsImageResource . }}
{{ $filters = $filters | append (images.Mask .) }}
{{ else }}
{{ errorf "mask is not a processable image" }}
{{ end }}
{{ else }}
{{ errorf "mask resource missing" }}
{{ end }} Prevention
- Use raster formats (PNG/JPEG) for masks, not SVG.
- Verify the resource resolves and is non-empty before masking.
- Keep mask assets version-controlled to detect corruption.
When it happens
Trigger: Calling images.Mask with a resource whose bytes are not a decodable image (wrong format, truncated, zero bytes, or a non-image media type that still passed the ImageSource interface).
Common situations: Mask resource path points to a non-image asset; the file is corrupt; remote fetch returned HTML/JSON instead of an image; or the format (e.g. AVIF/HEIC) is not supported by the decoder.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode image: %s
- invalid font source: %s
- aligny must be one of top, center, bottom
- invalid text font source: %T
- the padding filter requires between 1 and 5 arguments
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/6c0768529328728f.
Report an issue: GitHub.