gohugoio/hugo · error
failed to decode %q: %w
Error message
failed to decode %q: %w
What it means
Raised in decodeConfigFromParams (allconfig.go:1218) when a single config section's decoder fails; v.key is the section name (e.g. "markup", "outputs", "imaging", "languages"). Hugo decodes the raw config map section-by-section via registered decodeWeight setups in dependency order, and wraps the first decoder failure with its section key so the user knows which top-level block is malformed.
Source
Thrown at config/allconfig/allconfig.go:1218
} else {
logger.Warnf("Skip unknown config key %q", key)
}
}
}
// Sort them to get the dependency order right.
sort.Slice(decoderSetups, func(i, j int) bool {
ki, kj := decoderSetups[i], decoderSetups[j]
if ki.weight == kj.weight {
return ki.key < kj.key
}
return ki.weight < kj.weight
})
for _, v := range decoderSetups {
p := decodeConfig{p: p, c: target, fs: fs, bcfg: bcfg, logger: logger}
if err := v.decode(v, p); err != nil {
return fmt.Errorf("failed to decode %q: %w", v.key, err)
}
}
return nil
}
func createDefaultOutputFormats(allFormats output.Formats) map[string][]string {
if len(allFormats) == 0 {
panic("no output formats")
}
rssOut, rssFound := allFormats.GetByName(output.RSSFormat.Name)
htmlOut, _ := allFormats.GetByName(output.HTMLFormat.Name)
defaultListTypes := []string{htmlOut.Name}
if rssFound {
defaultListTypes = append(defaultListTypes, rssOut.Name)
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Identify the section from the quoted key in the message and inspect the wrapped inner error for the exact field.
- Compare the section against the current Hugo docs schema for that key; fix types (map vs list vs scalar).
- Bisect by commenting out the named section to confirm, then reintroduce fields incrementally.
- If the error appeared after a Hugo upgrade, check the release notes for config schema changes in that section.
Example fix
# before [imaging] quality = "high" # after [imaging] quality = 75
Defensive patterns
Strategy: validation
Validate before calling
// The error names the config section that failed to decode.
// Pre-check top-level sections are tables of the expected shape:
known := map[string]bool{"params": true, "markup": true, "outputs": true /* ... */}
for k, v := range rootCfg {
if known[k] {
if _, ok := v.(map[string]any); !ok && k != "outputs" {
return fmt.Errorf("%q must be a table, got %T", k, v)
}
}
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to decode") {
// The %q in the message names the offending section (e.g. "markup", "outputs")
return fmt.Errorf("fix the named config section's structure/types, then reload: %w", err)
} Prevention
- Read the quoted section name in the error and check that exact block
- Match the documented type for each section (table vs array vs scalar)
- Validate with `hugo config` after every config edit
- Avoid copying config snippets across Hugo versions without checking the current docs
When it happens
Trigger: Any top-level config section whose structure fails mapstructure decoding or the section's own validation — e.g. invalid `imaging.quality` out of range, malformed `outputFormats`, invalid `permalinks` patterns, bad `security` policy values, or wrong types anywhere in a known section.
Common situations: Typos and wrong value types after hand-editing hugo.toml/yaml, upgrading Hugo across versions where a section's schema changed (e.g. markup, pagination), or merging theme example configs with incompatible structures.
Related errors
- redirects must have either From or FromRe set
- failed to create config from result: %w
- failed to create config: %w
- failed to decode config for language %q: %w
- language name cannot be empty
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/16cc1c1adcec91ec.json.
Report an issue: GitHub ↗.