spf13/viper · error
encoder not found for this format
Error message
encoder not found for this format
What it means
Returned by DefaultCodecRegistry.Encoder (encoding.go:132-138) when r.codec(format) finds no match. The built-in registry only ships codecs for yaml/yml, json, toml, and dotenv/env (encoding.go:166-178); any other format string yields this error. It surfaces through marshalWriter (viper.go:1818) whenever Viper serializes config to a file or io.Writer.
Source
Thrown at encoding.go:135
// Format is case-insensitive.
func (r *DefaultCodecRegistry) RegisterCodec(format string, codec Codec) error {
r.init()
r.mu.Lock()
defer r.mu.Unlock()
r.codecs[strings.ToLower(format)] = codec
return nil
}
// Encoder implements the [EncoderRegistry] interface.
//
// Format is case-insensitive.
func (r *DefaultCodecRegistry) Encoder(format string) (Encoder, error) {
encoder, ok := r.codec(format)
if !ok {
return nil, errors.New("encoder not found for this format")
}
return encoder, nil
}
// Decoder implements the [DecoderRegistry] interface.
//
// Format is case-insensitive.
func (r *DefaultCodecRegistry) Decoder(format string) (Decoder, error) {
decoder, ok := r.codec(format)
if !ok {
return nil, errors.New("decoder not found for this format")
}
return decoder, nil
}
func (r *DefaultCodecRegistry) codec(format string) (Codec, bool) {View on GitHub (pinned to 528f7416c4)
Solutions
- Write to a format with a built-in codec: use an extension of json, yaml/yml, toml, or dotenv/env (SetConfigType or filename ext).
- If you must write hcl/ini/properties/etc., construct a DefaultCodecRegistry, call RegisterCodec("hcl", myCodec), and pass it via v := NewWithOptions(WithEncoderRegistry(r)) or WithCodecRegistry(r).
- Verify the format is actually registered before writing: guard with slices.Contains([]string{"json","yaml","yml","toml","env","dotenv"}, configType).
Example fix
// before
v.SetConfigName("app")
v.SetConfigType("hcl")
v.AddConfigPath("/etc/myapp")
_ = v.WriteConfig() // -> ConfigMarshalError: encoder not found for this format
// after (option A: use built-in codec)
v.SetConfigType("yaml")
_ = v.WriteConfig()
// after (option B: register an HCL codec)
r := NewCodecRegistry()
_ = r.RegisterCodec("hcl", myHCLCodec{})
v := NewWithOptions(WithCodecRegistry(r)) Defensive patterns
Strategy: validation
Validate before calling
// Confirm a built-in codec exists before writing.
var hasBuiltinEncoder = map[string]bool{"json": true, "yaml": true, "yml": true, "toml": true, "env": true, "dotenv": true}
func canEncode(format string) bool { return hasBuiltinEncoder[strings.ToLower(format)] }
// usage
cfgType := strings.ToLower(v.GetConfigType())
if cfgType == "" { cfgType = strings.TrimPrefix(filepath.Ext(outPath), ".") }
if !canEncode(cfgType) {
// register a codec via NewCodecRegistry().RegisterCodec(cfgType, codec), or switch extension
} Try / catch
if err := v.WriteConfig(); err != nil {
var marshalErr viper.ConfigMarshalError
if errors.As(err, &marshalErr) {
// encoder missing -> register a codec or change format
}
} Prevention
- Treat SupportedExts as 'recognized extensions', not 'formats with codecs'; only json/yaml/yml/toml/env/dotenv ship encoders.
- Pin codec availability in a unit test that calls WriteConfig for every format your app writes.
- When introducing a custom format, register its codec once at process start via WithCodecRegistry.
When it happens
Trigger: Calling WriteConfig, WriteConfigAs, SafeWriteConfig, or WriteConfigTo when the resolved configType (filename extension or SetConfigType value) is one of the SupportedExts entries that has no built-in codec in this version — 'ini', 'hcl', 'tfvars', 'properties', 'props', 'prop' — or any custom/unregistered format string. marshalWriter calls v.encoderRegistry.Encoder(configType) and wraps the result in ConfigMarshalError.
Common situations: Upgrading from an older Viper that bundled HCL/INI/properties encoders; switching a YAML app to write .hcl/.ini; passing a custom registry via WithEncoderRegistry that forgot RegisterCodec for the format you write; typo in the file extension.
Related errors
- decoder not found for this format
- missing configuration for 'configPath'
- config type could not be determined for %s
AI-assisted analysis of spf13/viper@528f7416c4 (2026-08-04).
Data as JSON: /data/errors/fa82535d1b3f2a24.json.
Report an issue: GitHub.