gohugoio/hugo · error

invalid webp config: %w

Error message

invalid webp config: %w

What it means

Wrapper error returned by ImagingConfig.init() when the WebP sub-configuration (cfg.Webp.init) fails validation. The %w verb wraps the specific underlying failure so the root cause (hint, method, compression, or quality) is preserved in the error chain. This is a fail-fast config validation that runs at Hugo startup when the [imaging] namespace is decoded.

Source

Thrown at resources/images/config.go:571

}

var validMetaSources = map[string]bool{
	"exif": true,
	"iptc": true,
	"xmp":  true,
}

func (cfg *ImagingConfig) init() error {
	cfg.BgColor = strings.ToLower(strings.TrimPrefix(cfg.BgColor, "#"))
	cfg.Anchor = strings.ToLower(cfg.Anchor)
	cfg.ResampleFilter = strings.ToLower(cfg.ResampleFilter)
	cfg.Hint = strings.ToLower(cfg.Hint)
	cfg.Compression = strings.ToLower(cfg.Compression)
	if err := cfg.Jpeg.init(cfg); err != nil {
		return fmt.Errorf("invalid jpeg config: %w", err)
	}
	if err := cfg.Webp.init(cfg); err != nil {
		return fmt.Errorf("invalid webp config: %w", err)
	}
	if err := cfg.Avif.init(cfg); err != nil {
		return fmt.Errorf("invalid avif config: %w", err)
	}
	if cfg.Quality < 0 || cfg.Quality > 100 {
		return fmt.Errorf("imaging.quality must be between 1 and 100 inclusive, got %d", cfg.Quality)
	}

	if cfg.Anchor == "" {
		cfg.Anchor = smartCropIdentifier
	}

	if strings.TrimSpace(cfg.Exif.IncludeFields) == "" && strings.TrimSpace(cfg.Exif.ExcludeFields) == "" {
		// Don't change this for no good reason. Please don't.
		cfg.Exif.ExcludeFields = "GPS|Exif|Exposure[M|P|B]|Contrast|Resolution|Sharp|JPEG|Metering|Sensing|Saturation|ColorSpace|Flash|WhiteBalance"
	}

	if len(cfg.Meta.Fields) == 0 {

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Read the wrapped error chain — the underlying message names the exact WebP field and allowed values (e.g. 'imaging.webp.method must be between 0 and 6, got 7').
  2. Open hugo.toml and fix the [imaging.webp] values: hint ∈ {picture,photo,drawing,icon,text}, method ∈ [0,6], compression ∈ {lossy,lossless}, quality ∈ [1,100].
  3. If you don't need custom WebP settings, remove the entire [imaging.webp] section to fall back to the defaults (lossy compression, photo hint, method 2, quality 75).

Example fix

# before (hugo.toml)
[imaging.webp]
quality = 90
method = 7
compression = "losless"

# after
[imaging.webp]
quality = 90
method = 6
compression = "lossless"
Defensive patterns

Strategy: validation

Validate before calling

// Validate WebP config before calling init()
func validateWebpConfig(w WebpConfig, globalQuality int) error {
    validHints := map[string]bool{"picture":true,"photo":true,"drawing":true,"icon":true,"text":true}
    h := strings.ToLower(w.Hint)
    if h != "" && !validHints[h] {
        return fmt.Errorf("invalid webp hint %q", h)
    }
    if w.Method < 0 || w.Method > 6 {
        return fmt.Errorf("webp method %d out of range [0,6]", w.Method)
    }
    c := strings.ToLower(w.Compression)
    if c != "" && c != "lossy" && c != "lossless" {
        return fmt.Errorf("invalid webp compression %q", c)
    }
    q := w.Quality; if q == 0 { q = globalQuality }; if q == 0 { q = 75 }
    if q < 1 || q > 100 {
        return fmt.Errorf("webp quality %d out of range [1,100]", q)
    }
    return nil
}

Prevention

When it happens

Trigger: Setting [imaging.webp] in hugo.toml with an invalid hint value (e.g. "photograph"), a method outside 0-6, a compression string other than lossy/lossless, or a quality outside 1-100. Also triggered programmatically by constructing an ImagingConfig with an invalid WebpConfig and calling init().

Common situations: Copying an imaging config from an outdated blog post or different Hugo version; typos like "lossles" in compression; setting webp.method to 7 (off-by-one from the 0-6 range); mixing up AVIF settings into the WebP section.

Related errors


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