VictoriaMetrics/VictoriaMetrics · error
cannot open %q: %w
Error message
cannot open %q: %w
What it means
DeletePath failed to open the file for deletion. Missing files (ENOENT) are treated as success (already deleted via symlink), but any other open error — permission, I/O, or a path that is a directory without proper access — is wrapped in this error and stops the deletion.
Source
Thrown at lib/backup/fslocal/fslocal.go:228
return nil
})
}
// DeletePath deletes the given path from fs and returns the size for the deleted file.
//
// The path must be in canonical form, e.g. it must have `/` directory separators
func (fs *FS) DeletePath(path string) (uint64, error) {
p := common.Part{
Path: path,
}
fullPath := fs.path(p)
f, err := os.Open(fullPath)
if err != nil {
if os.IsNotExist(err) {
// The file could be deleted earlier via symlink.
return 0, nil
}
return 0, fmt.Errorf("cannot open %q: %w", path, err)
}
fi, err := f.Stat()
_ = f.Close()
if err != nil {
return 0, fmt.Errorf("cannot stat %q at %q: %w", path, fullPath, err)
}
size := uint64(fi.Size())
if err := os.Remove(fullPath); err != nil {
return 0, fmt.Errorf("cannot remove %q: %w", fullPath, err)
}
return size, nil
}
// RemoveEmptyDirs recursively removes all the empty directories in fs.
func (fs *FS) RemoveEmptyDirs() error {
return fscommon.RemoveEmptyDirs(fs.Dir)
}
View on GitHub (pinned to 5079fb58f1)
Solutions
- Read the wrapped errno: EACCES/EPERM — fix ownership/permissions (chown -R) so the deleting user can open the file; ELOOP — remove the symlink cycle
- Check for immutable attributes: lsattr / chattr -i on the affected path
- Verify the mount is healthy (dmesg) if EIO is reported, then retry the deletion
- Run deletion as the same user that owns the backup directory
Example fix
// before: files owned by root after a manual restore // after: sudo chown -R victoria-metrics:victoria-metrics /var/lib/victoria-metrics sudo chattr -i /var/lib/victoria-metrics/data/... # if immutable
Defensive patterns
Strategy: try-catch
Validate before calling
// before deleting, verify the path is openable by the current user
full := filepath.Join(fs.Dir, filepath.FromSlash(canonicalPath))
f, err := os.Open(full)
if err != nil {
if !os.IsNotExist(err) { return fmt.Errorf("pre-delete check failed: %w", err) }
} else { f.Close() }
// also check write permission on parent dir (unlink requirement)
if err := unix.Access(filepath.Dir(full), unix.W_OK); err != nil {
return fmt.Errorf("no write perm on parent dir: %w", err)
} Try / catch
n, err := fs.DeletePath(path)
if err != nil {
var pe *os.PathError
if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.EACCES) || errors.Is(pe.Err, syscall.EPERM)) {
return fmt.Errorf("fix ownership/permissions for %s: %w", path, err)
}
return err
} Prevention
- Run retention/deletion as the same user that owns the backup files
- Avoid chattr +i on data-dir files that retention may delete
- Keep all files in one mount/ownership domain; avoid restore-as-root followed by service-user deletion
- Check for symlink cycles if ELOOP appears in the wrapped error
When it happens
Trigger: os.Open(fullPath) fails with a non-IsNotExist error while deleting canonical path `path` under fs.Dir: EACCES/EPERM on the file or a parent directory, EIO from storage, or ELOOP from a symlink cycle.
Common situations: Files created by a different user (root) inside the data dir while deletion runs as a service user; immutable flags (chattr +i) on old backup parts; broken mounts returning I/O errors; permission drift after restore-as-root.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- cannot delete `backup complete` file at %s: %w
- cannot open directory: %w
- cannot append files %q: %w
- cannot open file %q: %w
- cannot remove %q: %w
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/e211f4fe90406801.
Report an issue: GitHub.