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

  1. Rename the file to use a supported extension: .yaml/.yml, .json, .toml, .org, .csv, or .xml.
  2. If loading via UnmarshalFileToMap programmatically, validate the extension before calling.
  3. 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

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


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)