Billionmail/BillionMail · error
failed to create backup for %s: %v
Error message
failed to create backup for %s: %v
What it means
createBackups snapshots Postfix main.cf and master.cf before ApplyConfigsWithRollback modifies them. When ioutil.WriteFile cannot write the timestamped backup file (<path>.backup.<UnixNano>), the whole apply operation aborts before any change is made. This means the backup directory is not writable or the filesystem is broken.
Source
Thrown at core/internal/service/multi_ip_domain/config_manager.go:94
return nil
}
// createBackups Create backups for Postfix's main.cf and master.cf
func (m *ConfigManager) createBackups(ctx context.Context) (map[string]string, error) {
backups := make(map[string]string)
files := []string{PostfixMainCfPath, PostfixMasterCfPath}
for _, file := range files {
if gfile.Exists(file) {
content, err := ioutil.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %v", file, err)
}
backupPath := fmt.Sprintf("%s.backup.%d", file, time.Now().UnixNano())
if err := ioutil.WriteFile(backupPath, content, 0644); err != nil {
return nil, fmt.Errorf("failed to create backup for %s: %v", file, err)
}
g.Log().Debugf(ctx, "Created backup for %s at %s", file, backupPath)
backups[file] = backupPath
}
}
return backups, nil
}
// rollback Roll back configurations
func (m *ConfigManager) rollback(ctx context.Context, backups map[string]string) error {
var allErrors []string
for file, backup := range backups {
if gfile.Exists(backup) {
g.Log().Infof(ctx, "Rolling back %s from %s", file, backup)
content, err := ioutil.ReadFile(backup)
if err != nil {
err = fmt.Errorf("failed to read backup file %s: %v", backup, err)View on GitHub (pinned to fc36c76c05)
Solutions
- Check the wrapped %v OS error and fix filesystem permissions: chown/chmod the core/conf/postfix directory so the process user can write.
- Verify the volume is not mounted read-only (docker inspect the mount's RW flag); remount as writable.
- Free disk space or raise the quota on the filesystem holding the conf directory.
- If SELinux is enforcing, relabel with restorecon or adjust the container's SELinux policy.
Example fix
// before
if err := ioutil.WriteFile(backupPath, content, 0644); err != nil {
return nil, fmt.Errorf("failed to create backup for %s: %v", file, err)
}
// after
if err := os.MkdirAll(filepath.Dir(backupPath), 0o755); err != nil {
return nil, fmt.Errorf("backup dir unavailable: %v", err)
}
if err := ioutil.WriteFile(backupPath, content, 0o600); err != nil {
return nil, fmt.Errorf("failed to create backup for %s (check dir permissions/disk space): %v", file, err)
} Defensive patterns
Strategy: validation
Validate before calling
// before calling ApplyConfigsWithRollback
for _, f := range []string{multi_ip_domain.PostfixMainCfPath, multi_ip_domain.PostfixMasterCfPath} {
if fi, err := os.Stat(f); err == nil {
if err := syscall.Access(f, os.O_WRONLY); err != nil {
return fmt.Errorf("no write access to %s (or its dir): %v", f, err)
}
_ = fi
}
}
out, _ := exec.Command("df", "-h", filepath.Dir(multi_ip_domain.PostfixMainCfPath)).Output() // ensure free space Try / catch
if err := mgr.ApplyConfigsWithRollback(ctx, configs); err != nil {
if strings.Contains(err.Error(), "failed to create backup") {
// fix permissions/disk before retry; nothing was modified yet
}
} Prevention
- Ensure the process user owns conf/postfix and its parent directory.
- Mount conf volumes rw, never ro.
- Monitor free disk space on the conf volume.
- Run in a container as a non-root user with explicit chown at startup.
When it happens
Trigger: ioutil.WriteFile fails writing '<main.cf|master.cf>.backup.<unixnano>': read-only filesystem, missing write permission on conf/postfix dir, disk full, or the path is a directory.
Common situations: Container running with a read-only mount over ../conf/postfix; running as non-root user without ownership of the postfix conf dir; disk quota exhausted; SELinux/AppArmor denial.
Related errors
- failed to read backup file %s: %v
- error reading project configuration file: %v
- error writing project configuration file: %v
- error writing knowledge base file: %v
- error removing knowledge base file: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/f037ce87e2d1ef61.
Report an issue: GitHub.