gohugoio/hugo · error
is not a valid configuration format
Error message
%q is not a valid configuration format
What it means
Thrown by Decoder.UnmarshalFileToMap (parser/metadecoders/decoder.go:106) when FormatFromString(filename) returns an empty Format — meaning the file's extension is not one of Hugo's recognized config/data formats (yaml/yml, json, toml, org, csv, xml). Hugo refuses to guess and returns this error naming the offending filename.
Solutions
- Rename the file to use a supported extension: .yaml/.yml, .json, .toml, .org, .csv, or .xml.
- If loading via UnmarshalFileToMap programmatically, validate the extension before calling.
- Move non-data files out of the data/ directory.
Example fix
// before m, err := dec.UnmarshalFileToMap(fs, "data/notes.txt") // after m, err := dec.UnmarshalFileToMap(fs, "data/notes.json")
Defensive patterns
Strategy: validation
Validate before calling
// Reject filenames with unsupported extensions before UnmarshalFileToMap.
func supportedFormatFile(filename string) bool {
return metadecoders.FormatFromString(filename) != ""
} Try / catch
m, err := dec.UnmarshalFileToMap(fs, filename)
if err != nil {
return fmt.Errorf("unsupported config file %q: %w", filename, err)
} Prevention
- Use only .yaml/.yml/.json/.toml/.org/.csv/.xml under data/.
- Guard programmatically with FormatFromString before loading.
- Keep config extensions consistent across the project.
When it happens
Trigger: Calling UnmarshalFileToMap on a file like data.txt, config.ini, or foo.md where the extension does not map to a known Format; passing a filename with no extension; loading a /data file with an unsupported extension.
Common situations: Placing a data file with a .ini/.conf/.text extension under data/; referencing a config file with an unsupported extension in --config; typo in the file extension (e.g. .yalm instead of .yaml).
Related errors
- cannot unmarshal CSV into %T: invalid targetType: expected…
- invalid targetType: expected either slice or map, received
- unmarshal of format is not supported
- --appendPort=false not supported when in multihost mode
- cache dir contains unresolved placeholders
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/aad5b00f5a7f9238.
Report an issue: GitHub.
Appendix: source
Thrown at parser/metadecoders/decoder.go:106
if m == nil {
// We migrated to github.com/goccy/go-yaml in v0.152.0,
// which produces nil maps for empty YAML files (and empty map nodes), unlike gopkg.in/yaml.v2.
//
// To prevent crashes when trying to handle empty config files etc., we ensure we always return a non-nil map here.
// See issue 14074.
m = make(map[string]any)
}
return m, err
}
// UnmarshalFileToMap is the same as UnmarshalToMap, but reads the data from
// the given filename.
func (d Decoder) UnmarshalFileToMap(fs afero.Fs, filename string) (map[string]any, error) {
format := FormatFromString(filename)
if format == "" {
return nil, fmt.Errorf("%q is not a valid configuration format", filename)
}
data, err := afero.ReadFile(fs, filename)
if err != nil {
return nil, err
}
return d.UnmarshalToMap(data, format)
}
// UnmarshalStringTo tries to unmarshal data to a new instance of type typ.
func (d Decoder) UnmarshalStringTo(data string, typ any) (any, error) {
data = strings.TrimSpace(data)
// We only check for the possible types in YAML, JSON and TOML.
switch typ.(type) {
case string:
return data, nil
case map[string]any, hmaps.Params:
format := d.FormatFromContentString(data)View on GitHub (pinned to 52c9bd7908)