caddyserver/caddy · error

provisioning fallback encoder module: %v

Error message

provisioning fallback encoder module: %v

What it means

JournaldEncoder.Provision returns this when no wrapped encoder was configured, so it falls back to a default JSONEncoder, and that fallback's own Provision fails. In practice the fallback is a plain JSONEncoder whose Provision only fails if its nested format/writer module cannot load, making this a rare inner-module provisioning failure.

Source

Thrown at modules/logging/journaldencoder.go:72

}

// CaddyModule returns the Caddy module information.
func (JournaldEncoder) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "caddy.logging.encoders.journald",
		New: func() caddy.Module { return new(JournaldEncoder) },
	}
}

// Provision sets up the encoder.
func (je *JournaldEncoder) Provision(ctx caddy.Context) error {
	je.ctx = ctx

	if je.WrappedRaw == nil {
		je.Encoder = &JSONEncoder{}
		if p, ok := je.Encoder.(caddy.Provisioner); ok {
			if err := p.Provision(ctx); err != nil {
				return fmt.Errorf("provisioning fallback encoder module: %v", err)
			}
		}
		je.wrappedIsDefault = true
	} else {
		val, err := ctx.LoadModule(je, "WrappedRaw")
		if err != nil {
			return fmt.Errorf("loading wrapped encoder module: %v", err)
		}
		je.Encoder = val.(zapcore.Encoder)
	}

	suppressConsoleEncoderTimestamp(je.Encoder)

	return nil
}

// ConfigureDefaultFormat will set the default wrapped format to "console"
// if the writer is a terminal. If already configured, it passes through

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Explicitly set a wrapped encoder in the journald block (e.g. format json or format console) so the fallback path is not used
  2. Inspect the wrapped error (%v) to find the real inner cause and fix that config
  3. Run 'caddy validate --config <file>' to catch the nested module error before deploy

Example fix

# before
(logs journald) # no format -> implicit fallback

# after
log {
    output journald
    format journald {
        format json
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if err := caddy.Validate(cfg); err != nil { return err } // surfaces inner provisioning errors early

Try / catch

if err := je.Provision(ctx); err != nil {
    if strings.Contains(err.Error(), "provisioning fallback encoder") {
        // set an explicit wrapped encoder and retry provisioning
    }
    return fmt.Errorf("journald encoder setup: %w", err)
}

Prevention

When it happens

Trigger: A 'journald' log encoder block in config with no 'format'/wrapped encoder inside it, where constructing or provisioning the implicit JSON encoder errors (e.g. malformed nested module JSON injected via the API).

Common situations: Hand-written JSON logs config using caddy.logging.encoders.journald without a wrap; API-driven config pushes that include invalid nested encoder fields; version changes altering the default encoder's provisioning behavior.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/7aacdbc56430076d. Report an issue: GitHub.