{"record":{"id":"644875a0acf2c559","repo":"caddyserver/caddy","slug":"setting-up-sink-log-v","errorCode":null,"errorMessage":"setting up sink log: %v","messagePattern":"setting up sink log: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"logging.go","lineNumber":99,"sourceCode":"}\n\n// openLogs sets up the config and opens all the configured writers.\n// It closes its logs when ctx is canceled, so it should clean up\n// after itself.\nfunc (logging *Logging) openLogs(ctx Context) error {\n\t// make sure to deallocate resources when context is done\n\tctx.OnCancel(func() {\n\t\terr := logging.closeLogs()\n\t\tif err != nil {\n\t\t\tLog().Error(\"closing logs\", zap.Error(err))\n\t\t}\n\t})\n\n\t// set up the \"sink\" log first (std lib's default global logger)\n\tif logging.Sink != nil {\n\t\terr := logging.Sink.provision(ctx, logging)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"setting up sink log: %v\", err)\n\t\t}\n\t}\n\n\t// as a special case, set up the default structured Caddy log next\n\tif err := logging.setupNewDefault(ctx); err != nil {\n\t\treturn err\n\t}\n\n\t// then set up any other custom logs\n\tfor name, l := range logging.Logs {\n\t\t// the default log is already set up\n\t\tif name == DefaultLoggerName {\n\t\t\tcontinue\n\t\t}\n\n\t\terr := l.provision(ctx, logging)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"setting up custom log '%s': %v\", name, err)","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/logging.go#L81-L117","documentation":"During Logging.Provision, the 'sink' logger (which captures the Go standard library's global logger) is provisioned first. This error wraps any failure from that setup, e.g. its writer module failing to load or open.","triggerScenarios":"Config with logging.sink containing an invalid writer (bad module name, unreadable file path, bad log rolling options for file writers). The failure happens at config provision time, before any other logs start.","commonSituations":"JSON configs defining \"sink\": { \"writer\": {...} } with a typo'd writer type or a directory the Caddy user cannot write to; adapting examples that reference enterprise-only writer modules not compiled into the build.","solutions":["Check the wrapped error for the real cause (module load vs writer open).","Fix or remove the sink writer config; omitting it uses stderr defaults.","Ensure writer modules (e.g. file with rolling) have valid options and writable paths.","If using a custom-compiled Caddy, confirm the writer module is included in the build."],"exampleFix":"// before\n\"logging\": { \"sink\": { \"writer\": { \"output\": \"fil\" } } }\n// after\n\"logging\": { \"sink\": { \"writer\": { \"output\": \"file\", \"filename\": \"/var/log/caddy-sink.log\" } } }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := cfg.Provision(ctx); err != nil {\n    if strings.Contains(err.Error(), \"setting up sink log\") {\n        // fix/remove logging.sink writer config, re-provision\n    }\n}","preventionTips":["Run 'caddy validate' on configs with sink sections before deploy.","Keep the sink writer minimal (stderr/file)."],"tags":["logging","provision","config"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}