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.Name

View on GitHub (pinned to 7586a4d1bd)

Solutions

  1. Check the wrapped OS error (EACCES, ENOENT, EIO).
  2. Ensure the metadata file is owned/readable by the rqlited user: ls -l <dir>; chown/chmod as needed.
  3. Stop concurrent processes that delete files from the backup directory.
  4. If ENOENT (deleted between check and read), simply retry — CurrentMetadata tolerates a missing file by returning (nil, nil).
  5. 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

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


AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03). Data as JSON: /api/errors/f9203bc23139fcba. Report an issue: GitHub.