{"record":{"id":"d3b0ffe354add716","repo":"cloudreve/cloudreve","slug":"failed-to-write-config-file-w","errorCode":null,"errorMessage":"failed to write config file: %w","messagePattern":"failed to write config file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/conf/conf.go","lineNumber":46,"sourceCode":"\n// NewIniConfigProvider initializes a new Ini config file provider. A default config file\n// will be created if the given path does not exist.\nfunc NewIniConfigProvider(configPath string, l logging.Logger) (ConfigProvider, error) {\n\tif configPath == \"\" || !util.Exists(configPath) {\n\t\tl.Info(\"Config file %q not found, creating a new one.\", configPath)\n\t\t// 创建初始配置文件\n\t\tconfContent := util.Replace(map[string]string{\n\t\t\t\"{SessionSecret}\": util.RandStringRunesCrypto(64),\n\t\t}, defaultConf)\n\t\tf, err := util.CreatNestedFile(configPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create config file: %w\", err)\n\t\t}\n\n\t\t// 写入配置文件\n\t\t_, err = f.WriteString(confContent)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to write config file: %w\", err)\n\t\t}\n\n\t\tf.Close()\n\t}\n\n\tcfg, err := ini.Load(configPath, []byte(getOverrideConfFromEnv(l)))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse config file %q: %w\", configPath, err)\n\t}\n\n\tprovider := &iniConfigProvider{\n\t\tdatabase:        *DatabaseConfig,\n\t\tsystem:          *SystemConfig,\n\t\tssl:             *SSLConfig,\n\t\tunix:            *UnixConfig,\n\t\tslave:           *SlaveConfig,\n\t\tredis:           *RedisConfig,\n\t\tcors:            *CORSConfig,","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/cloudreve/cloudreve/blob/20c95ad73f3a8bcb72887fea91ff31ab24fa1011/pkg/conf/conf.go#L28-L64","documentation":"Thrown by NewIniConfigProvider (pkg/conf/conf.go:46) when the freshly created config file was opened but f.WriteString(confContent) fails to write the rendered default template. The file handle is valid, so this is an I/O-time failure: disk full (ENOSPC), quota exceeded, device/FS-level write errors (NFS stale handle, disk detached), or the file was opened on a filesystem that went read-only. Startup aborts because the config was never persisted.","triggerScenarios":"First-run generation of the INI file on a full disk; writing across a network mount that drops mid-write; the underlying ext4 flipped to read-only after detecting errors; cgroup/FS quota exhaustion in containers.","commonSituations":"Small VPS or container with a full volume; config dir on NFS/SMB with intermittent availability; container ephemeral storage limit reached; hardware disk failing and kernel remounts ro.","solutions":["Free space or raise the quota on the volume holding the config path (df -h to confirm)","If the FS remounted read-only, check dmesg for disk errors, fix, and remount rw","Move the config path to a reliably writable local volume","For containers, increase ephemeral-storage limits or write config to a mounted volume"],"exampleFix":"# before\n$ ./cloudreve\nfailed to write config file: write /cloudreve/conf.ini: no space left on device\n\n# after\n$ df -h /cloudreve\n$ docker system prune   # or extend the volume\n$ ./cloudreve","handlingStrategy":"validation","validationCode":"// free-space preflight for the config volume\nfunc checkDiskSpace(dir string, need uint64) error {\n    var st syscall.Statfs_t\n    if err := syscall.Statfs(dir, &st); err != nil {\n        return err\n    }\n    if uint64(st.Bavail)*uint64(st.Bsize) < need {\n        return fmt.Errorf(\"less than %d bytes free on %s\", need, dir)\n    }\n    return nil\n}","typeGuard":"func isDiskFull(err error) bool {\n    return err != nil && (errors.Is(err, syscall.ENOSPC) || strings.Contains(err.Error(), \"no space left on device\"))\n}","tryCatchPattern":"provider, err := conf.NewIniConfigProvider(configPath, l)\nif err != nil {\n    if isDiskFull(err) {\n        log.Fatalf(\"config volume is full; free space or extend the disk, then restart\")\n    }\n    log.Fatalf(\"config write failed: %v\", err)\n}","preventionTips":["Monitor free space on the config volume and alert well before zero","Keep config on a local reliable disk, not a flaky network mount","Set container ephemeral-storage limits with headroom","Watch dmesg for filesystem errors that force read-only remounts"],"tags":["go","config","filesystem","disk-full","startup"],"backgroundTag":null,"analyzedSha":"20c95ad73f3a8bcb72887fea91ff31ab24fa1011","analyzedAt":"2026-08-16T01:42:55.403Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}