gohugoio/hugo · error

failed to load translations: %w%s

Error message

failed to load translations: %w%s

What it means

Hugo's i18n TranslationProvider failed to parse a translation file with go-i18n's bundle.ParseMessageFileBytes. The wrapped error carries the underlying parse failure (invalid TOML/YAML/JSON, bad plural categories, or reserved keys mixed with unreserved keys), and Hugo appends extra guidance for the reserved-keys case. The error is wrapped with file context so the offending i18n file and position are shown.

Source

Thrown at langs/i18n/translationProvider.go:142

		}
		name = artificialLangTagPrefix + name
	}

	_, err = bundle.ParseMessageFileBytes(b, name)
	if err != nil {
		if strings.Contains(err.Error(), "no plural rule") {
			// https://github.com/gohugoio/hugo/issues/7798
			name = artificialLangTagPrefix + name
			_, err = bundle.ParseMessageFileBytes(b, name)
			if err == nil {
				return nil
			}
		}
		var guidance string
		if strings.Contains(err.Error(), "mixed with unreserved keys") {
			guidance = ": see the lang.Translate documentation for a list of reserved keys"
		}
		return errWithFileContext(fmt.Errorf("failed to load translations: %w%s", err, guidance), r)
	}

	return nil
}

// CloneResource sets the language func for the new language.
func (tp *TranslationProvider) CloneResource(dst, src *deps.Deps) error {
	dst.Translate = tp.getTranslateFunc(dst)
	return nil
}

func defaultLanguage(conf config.AllProvider) *langs.Language {
	key := conf.DefaultContentLanguage()
	for _, l := range conf.Languages().(langs.Languages) {
		if l.Lang == key {
			return l
		}
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Open the i18n file named in the error and fix the reported syntax/key problem at the given position.
  2. If the message mentions 'mixed with unreserved keys', restructure the entry: reserved plural keys (one, other, etc.) cannot share a map with arbitrary custom keys — see the lang.Translate docs for the reserved-key list.
  3. Remove plural categories not supported by that language's CLDR rules, or rename the file to the correct language code.
  4. Validate the file's TOML/YAML/JSON with a linter to catch format errors.

Example fix

# i18n/en.toml — before (reserved plural keys mixed with custom keys)
[readMore]
other = "Read more"
label = "link"

# after
[readMore]
other = "Read more"

[readMoreLabel]
other = "link"
Defensive patterns

Strategy: validation

Validate before calling

// Validate translation files parse before running hugo
// ls i18n/ && for f in i18n/*.toml; do tomlv "$f"; done
if _, err := toml.DecodeFile("i18n/en.toml", &v); err != nil { log.Fatal(err) }

Try / catch

if err := ss.Update(deps); err != nil {
    if strings.Contains(err.Error(), "failed to load translations") {
        // report offending i18n file/key to user
    }
    return err
}

Prevention

When it happens

Trigger: Loading any file under i18n/ (or a theme's i18n/) during site build. Specifically: syntax errors in the translation file; using reserved go-i18n keys (id, description, one, other, few, many, zero) mixed with custom sub-keys under one message; plural categories not valid for the file's language tag (Hugo retries with an artificial 'art-x-' tag prefix for the 'no plural rule' case, so this fires only when that retry also fails).

Common situations: Nesting custom keys alongside 'one'/'other' under a translation id; copying plural forms (e.g. 'few', 'many') into a language whose CLDR plural rules don't define them; malformed TOML/YAML after hand-editing; theme-provided i18n files incompatible after a go-i18n or Hugo upgrade; naming the file with an unparseable language code.

Related errors


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