rqlite/rqlite · error
failed to read file %s: %w
Error message
failed to read file %s: %w
What it means
(*Client).CurrentMetadata reads the JSON metadata file at the client's metaPath and wraps os.ReadFile errors with this message. It is only thrown when the metadata file exists (fileExists check) but cannot be read — i.e. a race, permissions, or I/O problem rather than a missing file.
Source
Thrown at auto/file/file.go:90
dir: dir,
name: name,
metaPath: filepath.Join(dir, "METADATA.json"),
}
if opt != nil {
c.timestamp = opt.Timestamp
}
return c, nil
}
// CurrentMetadata returns the current metadata.
func (c *Client) CurrentMetadata(ctx context.Context) (*Metadata, error) {
if !fileExists(c.metaPath) {
return nil, nil
}
data, err := os.ReadFile(c.metaPath)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %w", c.metaPath, err)
}
var md Metadata
if err := json.Unmarshal(data, &md); err != nil {
return nil, fmt.Errorf("failed to unmarshal metadata from file %s: %w", c.metaPath, err)
}
return &md, nil
}
// LatestFilePath returns the path to the most recently uploaded file.
func (c *Client) LatestFilePath(ctx context.Context) string {
md, err := c.CurrentMetadata(ctx)
if err != nil {
return ""
}
if md == nil {
return ""
}
return md.NameView on GitHub (pinned to 7586a4d1bd)
Solutions
- Check the wrapped OS error (EACCES, ENOENT, EIO).
- Ensure the metadata file is owned/readable by the rqlited user: ls -l <dir>; chown/chmod as needed.
- Stop concurrent processes that delete files from the backup directory.
- If ENOENT (deleted between check and read), simply retry — CurrentMetadata tolerates a missing file by returning (nil, nil).
- Check dmesg/filesystem health on persistent I/O errors.
Example fix
// caller-side resilient pattern
md, err := client.CurrentMetadata(ctx)
if err != nil {
if errors.Is(err, fs.ErrNotExist) { md = nil } else { return err }
} Defensive patterns
Strategy: try-catch
Validate before calling
// check readability before use
if info, err := os.Stat(metaPath); err == nil {
if f, err := os.Open(metaPath); err != nil { return err } else { f.Close() }
_ = info
} Try / catch
md, err := client.CurrentMetadata(ctx)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
md = nil // raced delete; treat as no metadata
} else {
return err
}
} Prevention
- Keep one writer per backup directory; avoid concurrent cleanup jobs.
- Ensure stable ownership/permissions on the metadata file and directory.
- Use local (non-NFS) storage where possible to avoid stale-handle EIO errors.
- Retry once on transient read errors before failing the backup cycle.
When it happens
Trigger: Calling CurrentMetadata (or CurrentID/LatestFilePath which use it) while the metadata file exists but os.ReadFile fails: permission changed mid-run, file deleted between the exists-check and the read, disk I/O error, or wrong ownership after manual intervention.
Common situations: Backup directory permissions tightened by an admin; metadata file removed by a concurrent cleanup job; NFS stale handles; multiple rqlited instances against the same directory with conflicting ownership.
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 temporary file in %s: %w
- failed to write temporary metadata file %s: %w
- failed to open database file: %s
- failed to create directory %s: %w
- failed to test writing to directory %s: %w
AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03).
Data as JSON: /api/errors/f9203bc23139fcba.
Report an issue: GitHub.