{"record":{"id":"e211f4fe90406801","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-open-q-w","errorCode":null,"errorMessage":"cannot open %q: %w","messagePattern":"cannot open %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/backup/fslocal/fslocal.go","lineNumber":228,"sourceCode":"\t\treturn nil\n\t})\n}\n\n// DeletePath deletes the given path from fs and returns the size for the deleted file.\n//\n// The path must be in canonical form, e.g. it must have `/` directory separators\nfunc (fs *FS) DeletePath(path string) (uint64, error) {\n\tp := common.Part{\n\t\tPath: path,\n\t}\n\tfullPath := fs.path(p)\n\tf, err := os.Open(fullPath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\t// The file could be deleted earlier via symlink.\n\t\t\treturn 0, nil\n\t\t}\n\t\treturn 0, fmt.Errorf(\"cannot open %q: %w\", path, err)\n\t}\n\tfi, err := f.Stat()\n\t_ = f.Close()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"cannot stat %q at %q: %w\", path, fullPath, err)\n\t}\n\tsize := uint64(fi.Size())\n\tif err := os.Remove(fullPath); err != nil {\n\t\treturn 0, fmt.Errorf(\"cannot remove %q: %w\", fullPath, err)\n\t}\n\treturn size, nil\n}\n\n// RemoveEmptyDirs recursively removes all the empty directories in fs.\nfunc (fs *FS) RemoveEmptyDirs() error {\n\treturn fscommon.RemoveEmptyDirs(fs.Dir)\n}\n","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/backup/fslocal/fslocal.go#L210-L246","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: files owned by root after a manual restore\n// after:\nsudo chown -R victoria-metrics:victoria-metrics /var/lib/victoria-metrics\nsudo chattr -i /var/lib/victoria-metrics/data/... # if immutable","handlingStrategy":"try-catch","validationCode":"// before deleting, verify the path is openable by the current user\nfull := filepath.Join(fs.Dir, filepath.FromSlash(canonicalPath))\nf, err := os.Open(full)\nif err != nil {\n    if !os.IsNotExist(err) { return fmt.Errorf(\"pre-delete check failed: %w\", err) }\n} else { f.Close() }\n// also check write permission on parent dir (unlink requirement)\nif err := unix.Access(filepath.Dir(full), unix.W_OK); err != nil {\n    return fmt.Errorf(\"no write perm on parent dir: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"n, err := fs.DeletePath(path)\nif err != nil {\n    var pe *os.PathError\n    if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.EACCES) || errors.Is(pe.Err, syscall.EPERM)) {\n        return fmt.Errorf(\"fix ownership/permissions for %s: %w\", path, err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["filesystem","go","permissions"],"backgroundTag":"permission-denied","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}