gohugoio/hugo · error

imaging.avif.quality must be between 1 and 100 inclusive…

Error message

imaging.avif.quality must be between 1 and 100 inclusive, got %d

What it means

Validates the AVIF quality after fallback resolution. If imaging.avif.quality is 0, it inherits the global imaging.quality; if that is also 0, it defaults to 60 (lower than JPEG/WebP because AVIF is more efficient). After resolution, quality must be between 1 and 100 inclusive.

Solutions

  1. Set imaging.avif.quality to a value between 1 and 100. AVIF typically looks good at 40-70.
  2. If you want lossless AVIF, set compression = 'lossless' instead of cranking quality to 100.
  3. Omit the quality key to use the default 60, which is a good starting point for web photographs.

Example fix

# before (hugo.toml)
[imaging.avif]
quality = 100
compression = "lossy"

# after
[imaging.avif]
quality = 55
compression = "lossy"
Defensive patterns

Strategy: validation

Validate before calling

// Validate AVIF quality (0 = inherit global or default 60)
func validateAvifQuality(q, globalQuality int) error {
    resolved := q
    if resolved == 0 { resolved = globalQuality }
    if resolved == 0 { resolved = 60 }
    if resolved < 1 || resolved > 100 {
        return fmt.Errorf("avif quality resolves to %d, out of range [1,100]", resolved)
    }
    return nil
}

Prevention

When it happens

Trigger: Setting [imaging.avif] quality in hugo.toml to a value below 1 or above 100. A value of 0 does not trigger this — it triggers the fallback to global quality or the default 60.

Common situations: Setting AVIF quality to the same value as JPEG quality (AVIF needs lower values for equivalent visual quality); setting quality above 100; setting it to 0 expecting lossless (use compression = 'lossless' instead).

Related errors


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

Appendix: source

Thrown at resources/images/config.go:728

	if c.Quality == 0 {
		c.Quality = 60
	}

	c.Hint = strings.ToLower(c.Hint)
	c.Compression = strings.ToLower(c.Compression)

	if c.Hint != "" && !hints[c.Hint] {
		return fmt.Errorf("imaging.avif.hint must be one of picture, photo, drawing, icon, or text, got %q", c.Hint)
	}
	if c.EncoderSpeed < 1 || c.EncoderSpeed > 10 {
		return fmt.Errorf("imaging.avif.encoderSpeed must be between 1 and 10, got %d", c.EncoderSpeed)
	}

	if c.Compression != "" && !compressionMethods[c.Compression] {
		return fmt.Errorf("imaging.avif.compression must be one of lossy or lossless, got %q", c.Compression)
	}
	if c.Quality < 1 || c.Quality > 100 {
		return fmt.Errorf("imaging.avif.quality must be between 1 and 100 inclusive, got %d", c.Quality)
	}

	return nil
}

// WebpConfig holds WebP-specific encoding configuration.
type WebpConfig struct {
	// Quality setting (1-100). Falls back to the global imaging.quality if unset.
	// Only relevant for lossy encoding.
	Quality int

	// Compression method to use.
	// One of "lossy" or "lossless".
	Compression string

	// Hint about what type of image this is.
	// Valid values are "picture", "photo", "drawing", "icon", or "text".
	// Default is "photo".

View on GitHub (pinned to 52c9bd7908)