{"record":{"id":"68e955f7b6e52c11","repo":"1Panel-dev/1Panel","slug":"fatal-error-config-file-s-n","errorCode":null,"errorMessage":"Fatal error config file: %s \\n","messagePattern":"Fatal error config file: (.+?) \\\\n","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"agent/init/viper/viper.go","lineNumber":34,"sourceCode":"\nfunc Init() {\n\tmode := \"\"\n\tfileOp := files.NewFileOp()\n\tv := viper.NewWithOptions()\n\tv.SetConfigType(\"yaml\")\n\n\tconfig := global.ServerConfig{}\n\tif err := yaml.Unmarshal(conf.AppYaml, &config); err != nil {\n\t\tpanic(err)\n\t}\n\tif config.Base.Mode != \"\" {\n\t\tmode = config.Base.Mode\n\t}\n\tif mode == \"dev\" && fileOp.Stat(\"/opt/1panel/conf/app.yaml\") {\n\t\tv.SetConfigName(\"app\")\n\t\tv.AddConfigPath(path.Join(\"/opt/1panel/conf\"))\n\t\tif err := v.ReadInConfig(); err != nil {\n\t\t\tpanic(fmt.Errorf(\"Fatal error config file: %s \\n\", err))\n\t\t}\n\t} else {\n\t\treader := bytes.NewReader(conf.AppYaml)\n\t\tif err := v.ReadConfig(reader); err != nil {\n\t\t\tpanic(fmt.Errorf(\"Fatal error config file: %s \\n\", err))\n\t\t}\n\t}\n\tv.OnConfigChange(func(e fsnotify.Event) {\n\t\tif err := v.Unmarshal(&global.CONF); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n\tserverConfig := global.ServerConfig{}\n\tif err := v.Unmarshal(&serverConfig); err != nil {\n\t\tpanic(err)\n\t}\n\n\tglobal.CONF = serverConfig","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/1Panel-dev/1Panel/blob/5ac7c808815b0691009cd390414f03471312262f/agent/init/viper/viper.go#L16-L52","documentation":"Panic in the agent's viper init when mode=='dev' and /opt/1panel/conf/app.yaml exists but viper's ReadInConfig fails — typically UnsupportedConfigError (the file extension is not a recognized format) or a malformed file. The message wraps the underlying viper error with 'Fatal error config file: %s'.","triggerScenarios":"agent/init/viper/viper.go: SetConfigName(\"app\") + AddConfigPath(\"/opt/1panel/conf\") then v.ReadInConfig() returns an error, e.g. app.yaml contains tabs or invalid YAML, or app.yaml is actually named/aliased to a format viper cannot infer.","commonSituations":"Editing /opt/1panel/conf/app.yaml with tab indentation (YAML forbids tabs); truncated file after a crash; mode set to 'dev' in the embedded config while the on-disk dev file is broken.","solutions":["Validate the YAML: yamllint /opt/1panel/conf/app.yaml (or python -c 'import yaml,sys; yaml.safe_load(open(sys.argv[1]))' app.yaml) and fix tabs/syntax","Restore app.yaml from a backup or reinstall the config (1pctl reset or reinstall) to get a known-good file","If dev mode is unintended, change Base.Mode in the embedded app config so the code path reads the embedded bytes instead of the dev file"],"exampleFix":"# before (app.yaml with a tab)\nssl:\n\tssl-dir: /opt/1panel/ssl\n# after (spaces only)\nssl:\n  ssl-dir: /opt/1panel/ssl","handlingStrategy":"validation","validationCode":"python3 -c \"import yaml; yaml.safe_load(open('/opt/1panel/conf/app.yaml')); print('yaml ok')\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint /opt/1panel/conf/app.yaml after every manual edit (spaces, not tabs)","Keep a backup copy of the last working app.yaml and diff before restart"],"tags":["viper","yaml","config","go","panic"],"backgroundTag":null,"analyzedSha":"5ac7c808815b0691009cd390414f03471312262f","analyzedAt":"2026-08-15T14:02:06.953Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}