twpayne/chezmoi · error

%s: unknown encoding

Error message

%s: unknown encoding

What it means

This error is raised by chezmoi's template fimodule (internal/chezmoi/template.go:167) when an operation requests an encoding by name and the supplied string does not match any encoding known to that component. The message '%s: unknown encoding' identifies the offending name. In chezmoi this commonly happens with functions like encodeTemplateData/decrypt/encrypt-style helpers or .chezmoitemplate features that take a scheme argument (for example a base64/hex-style encoding name) where the value provided is misspelled, uses the wrong case, or is not supported by the fimodule's registered set. To fix it, check the ficode that passes the encoding name — usually in a template expression in your .chezmoi templates or .chezmoi.toml.tmpl — and replace the invalid value with one of the supported encoding names documented for that function (e.g. the accepted literal such as "base64").

Source

Thrown at internal/chezmoi/template.go:167

			key := string(keyValuePairMatch[1])
			value := maybeUnquote(string(keyValuePairMatch[2]))
			switch key {
			case "encoding":
				switch value {
				case "utf-8":
					o.Encoding = unicode.UTF8
				case "utf-8-bom":
					o.Encoding = unicode.UTF8BOM
				case "utf-16-be":
					o.Encoding = unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM)
				case "utf-16-be-bom":
					o.Encoding = unicode.UTF16(unicode.BigEndian, unicode.UseBOM)
				case "utf-16-le":
					o.Encoding = unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
				case "utf-16-le-bom":
					o.Encoding = unicode.UTF16(unicode.LittleEndian, unicode.UseBOM)
				default:
					return nil, fmt.Errorf("%s: unknown encoding", value)
				}
			case "format-indent":
				o.FormatIndent = value
			case "format-indent-width":
				switch width, err := strconv.Atoi(value); {
				case err != nil:
					return nil, err
				case width < 0:
					return nil, fmt.Errorf("%d: invalid format-indent-width", width)
				default:
					o.FormatIndent = strings.Repeat(" ", width)
				}
			case "left-delimiter":
				o.LeftDelimiter = value
			case "line-ending", "line-endings":
				switch string(keyValuePairMatch[2]) {
				case "crlf":
					o.LineEnding = "\r\n"

View on GitHub (pinned to f901167e46)

Solutions

  1. Use one of the supported values: utf-8, utf-16, utf-16-be, utf-16-be-bom, utf-16-le, utf-16-le-bom
  2. Fix spelling/dashes (e.g. utf-16-le not utf16le or utf-16LE)
  3. Remove the encoding directive if default UTF-8 output is acceptable

Example fix

// before
{{- /* encoding: utf-16LE */ -}}
// after
{{- /* encoding: utf-16-le */ -}}
Defensive patterns

Strategy: validation

Validate before calling

// validate encoding directive value against supported set
allowed := map[string]bool{
  "utf-8": true, "utf-16": true, "utf-16-be": true, "utf-16-be-bom": true,
  "utf-16-le": true, "utf-16-le-bom": true,
}
if !allowed[value] { return fmt.Errorf("unsupported encoding %q", value) }

Type guard

func isKnownEncoding(v string) bool {
  switch v {
  case "utf-8", "utf-16", "utf-16-be", "utf-16-be-bom", "utf-16-le", "utf-16-le-bom":
    return true
  }
  return false
}

Try / catch

tmpl, err := ParseTemplate(...)
if err != nil && strings.Contains(err.Error(), "unknown encoding") {
  return fmt.Errorf("use a supported encoding directive value (utf-8, utf-16, utf-16-be[-bom], utf-16-le[-bom]): %w", err)
}

Prevention

When it happens

Trigger: A template contains a directive like {{- /* encoding: utf-8-bom */ -}} or another misspelled/unsupported encoding name, hitting the default branch in parseAndRemoveDirectives.

Common situations: Misspelling e.g. 'utf-16le' instead of 'utf-16-le'; assuming arbitrary Go IANA encoding names are accepted; copying directives from other tooling with different naming conventions.

Related errors


AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01). Data as JSON: /api/errors/01f810851a0858ca. Report an issue: GitHub.