Billionmail/BillionMail · error
failed to read file %s: %v
Error message
failed to read file %s: %v
What it means
createBackups reads PostfixMainCfPath and PostfixMasterCfPath to snapshot them before config changes; this error wraps ioutil.ReadFile failure for one of those files and aborts the backup (and thus the whole ApplyConfigsWithRollback run, via the 'failed to create backup' wrapper).
Source
Thrown at core/internal/service/multi_ip_domain/config_manager.go:89
}
return fmt.Errorf("failed to apply configurations, but rollback succeeded: %v", err)
}
m.cleanupBackups(ctx, backups)
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 {View on GitHub (pinned to fc36c76c05)
Solutions
- Verify the file exists at the configured path constant and the process can read it (ls -l, check uid of the service)
- Fix permissions or run the service with access to /etc/postfix
- Re-check path constants PostfixMainCfPath/PostfixMasterCfPath match the actual deployment layout
- Handle ENOENT gracefully — if the file is optional, skip backup for it instead of failing the whole apply
Example fix
// before
content, err := ioutil.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %v", file, err)
}
// after
content, err := ioutil.ReadFile(file)
if err != nil {
if os.IsNotExist(err) {
continue // nothing to back up for this file
}
return nil, fmt.Errorf("failed to read file %s: %v", file, err)
} Defensive patterns
Strategy: validation
Validate before calling
func backupable(path string) error {
fi, err := os.Stat(path)
if err != nil { return err }
if !fi.Mode().IsRegular() { return fmt.Errorf("%s is not a regular file", path) }
f, err := os.Open(path)
if err != nil { return err }
return f.Close()
}
// run for both PostfixMainCfPath and PostfixMasterCfPath before applying Try / catch
err := manager.ApplyConfigsWithRollback(ctx, configs)
if err != nil {
var pathErr *fs.PathError
if errors.As(err, &pathErr) && (errors.Is(pathErr.Err, fs.ErrPermission) || errors.Is(pathErr.Err, fs.ErrNotExist)) {
// fix deployment/permissions before retrying
reportMisconfiguration(pathErr)
}
} Prevention
- Grant the service read permission on /etc/postfix configs
- Verify path constants match the container/deployment layout
- Don't delete postfix configs concurrently with backup operations
- Skip (rather than fail) backup for legitimately absent optional files
When it happens
Trigger: ioutil.ReadFile(file) fails on an existing file listed in files — typically EACCES (process lacks read permission), ENOENT via race (file deleted between gfile.Exists and ReadFile), or EISDIR/IO error.
Common situations: Running in a container without postfix config mounted or with restricted permissions; path constants pointing to the wrong location for the deployment; file removed concurrently by another tool; SELinux denials.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to create backup: %v
- failed to create backup for %s: %v
- failed to read backup file %s: %v
- failed to send confirmation email: %w
- failed to save private key: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/44b6ed22557d105e.
Report an issue: GitHub.