{"record":{"id":"7aacdbc56430076d","repo":"caddyserver/caddy","slug":"provisioning-fallback-encoder-module-v-7aacdb","errorCode":null,"errorMessage":"provisioning fallback encoder module: %v","messagePattern":"provisioning fallback encoder module: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/logging/journaldencoder.go","lineNumber":72,"sourceCode":"}\n\n// CaddyModule returns the Caddy module information.\nfunc (JournaldEncoder) CaddyModule() caddy.ModuleInfo {\n\treturn caddy.ModuleInfo{\n\t\tID:  \"caddy.logging.encoders.journald\",\n\t\tNew: func() caddy.Module { return new(JournaldEncoder) },\n\t}\n}\n\n// Provision sets up the encoder.\nfunc (je *JournaldEncoder) Provision(ctx caddy.Context) error {\n\tje.ctx = ctx\n\n\tif je.WrappedRaw == nil {\n\t\tje.Encoder = &JSONEncoder{}\n\t\tif p, ok := je.Encoder.(caddy.Provisioner); ok {\n\t\t\tif err := p.Provision(ctx); err != nil {\n\t\t\t\treturn fmt.Errorf(\"provisioning fallback encoder module: %v\", err)\n\t\t\t}\n\t\t}\n\t\tje.wrappedIsDefault = true\n\t} else {\n\t\tval, err := ctx.LoadModule(je, \"WrappedRaw\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"loading wrapped encoder module: %v\", err)\n\t\t}\n\t\tje.Encoder = val.(zapcore.Encoder)\n\t}\n\n\tsuppressConsoleEncoderTimestamp(je.Encoder)\n\n\treturn nil\n}\n\n// ConfigureDefaultFormat will set the default wrapped format to \"console\"\n// if the writer is a terminal. If already configured, it passes through","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/logging/journaldencoder.go#L54-L90","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Explicitly set a wrapped encoder in the journald block (e.g. format json or format console) so the fallback path is not used","Inspect the wrapped error (%v) to find the real inner cause and fix that config","Run 'caddy validate --config <file>' to catch the nested module error before deploy"],"exampleFix":"# before\n(logs journald) # no format -> implicit fallback\n\n# after\nlog {\n    output journald\n    format journald {\n        format json\n    }\n}","handlingStrategy":"try-catch","validationCode":"if err := caddy.Validate(cfg); err != nil { return err } // surfaces inner provisioning errors early","typeGuard":null,"tryCatchPattern":"if err := je.Provision(ctx); err != nil {\n    if strings.Contains(err.Error(), \"provisioning fallback encoder\") {\n        // set an explicit wrapped encoder and retry provisioning\n    }\n    return fmt.Errorf(\"journald encoder setup: %w\", err)\n}","preventionTips":["Always specify an explicit format inside journald blocks","Validate full config with 'caddy validate' before reload"],"tags":["caddy","logging","journald","provisioning"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}