gohugoio/hugo · error

MIME %q not supported

Error message

MIME %q not supported

What it means

Hugo's `transform.Unmarshal` template function was passed a Resource whose media type has no suffix mapping to a supported metadecoder format (JSON, TOML, YAML, CSV, XML). When no explicit `format` option is given, Hugo derives the format from the resource's MIME type suffixes via `metadecoders.FormatFromStrings`; if that yields nothing, this error is returned with the offending MIME type.

Source

Thrown at tpl/transform/unmarshal.go:84

		if key == "" {
			return nil, errors.New("no Key set in Resource")
		}

		if decoder != metadecoders.Default {
			key += decoder.OptionsKey()
		}

		v, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {
			var f metadecoders.Format
			if decoder.Format != "" {
				f = metadecoders.FormatFromString(decoder.Format)
				if f == "" {
					return nil, fmt.Errorf("format %q not supported", decoder.Format)
				}
			} else {
				f = metadecoders.FormatFromStrings(r.MediaType().Suffixes()...)
				if f == "" {
					return nil, fmt.Errorf("MIME %q not supported", r.MediaType())
				}
			}

			reader, err := r.ReadSeekCloser()
			if err != nil {
				return nil, err
			}
			defer reader.Close()

			b, err := io.ReadAll(reader)
			if err != nil {
				return nil, err
			}

			v, err := decoder.Unmarshal(b, f)
			if err != nil {
				return nil, err
			}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Pass the format explicitly: `transform.Unmarshal (dict "format" "json") $resource`.
  2. For remote resources, check the server's Content-Type header or rename/serve the file with a proper extension.
  3. Add the suffix to a supported media type in your site's `mediaTypes` configuration.
  4. Confirm the data is actually one of json, toml, yaml, csv, or xml — other formats are unsupported.

Example fix

{{/* before */}}
{{ $data := resources.GetRemote $url | transform.Unmarshal }}
{{/* after */}}
{{ $data := resources.GetRemote $url | transform.Unmarshal (dict "format" "json") }}
Defensive patterns

Strategy: validation

Validate before calling

{{ $supported := slice "application/json" "application/toml" "application/yaml" "application/xml" "text/csv" }}
{{ $r := resources.Get "data/file.json" }}
{{ if in $supported $r.MediaType.Type }}
  {{ $data := $r | transform.Unmarshal }}
{{ end }}

Try / catch

{{ $data := "" }}
{{ with try (transform.Unmarshal $r) }}
  {{ with .Err }}{{ warnf "unmarshal failed: %s" . }}{{ else }}{{ $data = .Value }}{{ end }}
{{ end }}

Prevention

When it happens

Trigger: Calling `{{ $data := resources.Get "file.ext" | transform.Unmarshal }}` (or `unmarshal`) on a resource whose media type (e.g. text/plain, image/png, application/octet-stream) doesn't map to json/toml/yaml/csv/xml, without passing an options map containing `format`.

Common situations: Fetching remote data with `resources.GetRemote` where the server returns a generic Content-Type like text/plain or application/octet-stream for a JSON/YAML payload; unmarshaling files with nonstandard extensions (.conf, .txt); custom mediaTypes config missing the needed suffix.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/7c81c4b3611da293.json. Report an issue: GitHub ↗.