{"record":{"id":"961cdc3d608e710c","repo":"caddyserver/caddy","slug":"reading-config-from-file-v","errorCode":null,"errorMessage":"reading config from file: %v","messagePattern":"reading config from file: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/main.go","lineNumber":172,"sourceCode":"\tif adapterName != \"\" && configFile == \"\" {\n\t\treturn nil, \"\", \"\", fmt.Errorf(\"cannot adapt config without config file (use --config)\")\n\t}\n\n\t// load initial config and adapter\n\tvar config []byte\n\tvar cfgAdapter caddyconfig.Adapter\n\tvar err error\n\tif configFile != \"\" {\n\t\tif configFile == \"-\" {\n\t\t\tconfig, err = io.ReadAll(os.Stdin)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, \"\", \"\", fmt.Errorf(\"reading config from stdin: %v\", err)\n\t\t\t}\n\t\t\tlogger.Info(\"using config from stdin\")\n\t\t} else {\n\t\t\tconfig, err = os.ReadFile(configFile)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, \"\", \"\", fmt.Errorf(\"reading config from file: %v\", err)\n\t\t\t}\n\t\t\tlogger.Info(\"using config from file\", zap.String(\"file\", configFile))\n\t\t}\n\t} else if adapterName == \"\" {\n\t\t// if the Caddyfile adapter is plugged in, we can try using an\n\t\t// adjacent Caddyfile by default\n\t\tcfgAdapter = caddyconfig.GetAdapter(\"caddyfile\")\n\t\tif cfgAdapter != nil {\n\t\t\tconfig, err = os.ReadFile(\"Caddyfile\")\n\t\t\tif errors.Is(err, fs.ErrNotExist) {\n\t\t\t\t// okay, no default Caddyfile; pretend like this never happened\n\t\t\t\tcfgAdapter = nil\n\t\t\t} else if err != nil {\n\t\t\t\t// default Caddyfile exists, but error reading it\n\t\t\t\treturn nil, \"\", \"\", fmt.Errorf(\"reading default Caddyfile: %v\", err)\n\t\t\t} else {\n\t\t\t\t// success reading default Caddyfile\n\t\t\t\tconfigFile = \"Caddyfile\"","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/main.go#L154-L190","documentation":"os.ReadFile on the explicitly given --config file failed, wrapped as 'reading config from file'. The underlying error is almost always 'no such file or directory' or 'permission denied' for that exact path.","triggerScenarios":"Typo'd or wrong-case path in --config; file exists but the running user lacks read permission; relative path interpreted against an unexpected working directory (systemd, cron).","commonSituations":"Service units with WorkingDirectory! set so a relative --config resolves wrong; permissions tightened on /etc/caddy; configs generated to a temp path that was cleaned up.","solutions":["Verify the path: ls -l <config> from the same user and working directory","Use an absolute path in --config, especially in service units","Fix read permissions on the file (and execute permission on parent dirs)"],"exampleFix":"# before\nExecStart=/usr/bin/caddy run --config Caddyfile\n\n# after\nExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile","handlingStrategy":"validation","validationCode":"# Resolve and stat the config before invoking caddy:\nCONFIG=$(realpath \"$CONFIG\")\n[ -r \"$CONFIG\" ] || { echo \"cannot read $CONFIG\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths in service units and cron jobs","Check readability as the same user that runs caddy"],"tags":["cli","configuration","file-not-found","permissions"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}