gohugoio/hugo · error
%q is not a valid configuration format
Error message
%q is not a valid configuration format
What it means
Decoder.UnmarshalFileToMap derives the data format from the filename's extension via FormatFromString; if the extension doesn't map to a known format (toml, yaml/yml, json, xml, csv, org), it returns this error rather than guessing. Hugo refuses to parse configuration/data files whose format it cannot identify.
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 8a468df065)
Solutions
- Rename the file so its extension matches its actual format: `.toml`, `.yaml`/`.yml`, `.json`, `.xml`, or `.org` (e.g. `hugo.toml`, `config/_default/params.yaml`).
- Fix typoed extensions (`.ymal` → `.yaml`, `.jsn` → `.json`).
- If the content is in one format but the extension says otherwise, convert the content or the extension so they agree — Hugo dispatches the parser purely on the extension.
Example fix
# before config/_default/params.ymal # after config/_default/params.yaml
Defensive patterns
Strategy: validation
Validate before calling
var supported = map[string]bool{".toml": true, ".yaml": true, ".yml": true, ".json": true, ".xml": true, ".csv": true, ".org": true}
func canDecode(filename string) bool { return supported[strings.ToLower(filepath.Ext(filename))] } Type guard
func isKnownFormat(f metadecoders.Format) bool { return f != "" } // FormatFromString returns "" for unknown Try / catch
if err != nil && strings.Contains(err.Error(), "not a valid configuration format") {
// report the file's extension; rename or convert to toml/yaml/json
} Prevention
- Check the file extension against supported formats (toml/yaml/json/xml/csv/org) before calling transform.Unmarshal or Decode
- Don't feed extension-less or misnamed files to data-driven templates; pass the format explicitly where the API allows
- Validate CMS/import pipelines emit correct extensions
When it happens
Trigger: Passing a filename with an unrecognized or missing extension to UnmarshalFileToMap — e.g. loading a config or theme config named `config.txt`, `hugo.conf`, `config` (no extension), or a data/config file with a typoed extension like `.ymal` or `.jsn`.
Common situations: Renaming `hugo.toml` to something nonstandard; editors saving `config.toml.bak` or `hugo.yaml.txt`; migrating from another SSG whose config file has a different extension; scripts generating config files without extensions.
Related errors
- failed to unmarshal config for path %q: %w
- failed to load config: %w
- invalid Highlight option: %s
- language %q not found
- unsupported format: %q
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/aad5b00f5a7f9238.json.
Report an issue: GitHub ↗.