rqlite/rqlite · error

failed to test writing to directory %s: %w

Error message

failed to test writing to directory %s: %w

What it means

After creating the directory, NewClient probes writability by creating and then removing a '.touch' file; failure to open the touch file produces this error. The directory exists but the process cannot write to it.

Source

Thrown at auto/file/file.go:66

	}

	// Validate file parameter for path traversal attacks and directory separators
	cleanFile := filepath.Clean(name)
	if strings.Contains(name, string(filepath.Separator)) ||
		strings.Contains(cleanFile, "..") ||
		filepath.IsAbs(cleanFile) ||
		cleanFile != name {
		return nil, fmt.Errorf("invalid file parameter: %s (must be a simple filename without path separators)", name)
	}

	// Ensure the destination directory exists and is writable
	if err := os.MkdirAll(dir, 0755); err != nil {
		return nil, fmt.Errorf("failed to create directory %s: %w", dir, err)
	}
	touchPath := filepath.Join(dir, ".touch")
	f, err := os.OpenFile(touchPath, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("failed to test writing to directory %s: %w", dir, err)
	}
	f.Close()
	os.Remove(touchPath)

	c := &Client{
		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) {

View on GitHub (pinned to 7586a4d1bd)

Solutions

  1. Check the wrapped OS error (typically EACCES/EROFS).
  2. Grant write permission to the running user: chmod u+w <dir> or chown the directory.
  3. Check SELinux/AppArmor audit logs if unix permissions look correct.
  4. Ensure the mount is read-write (mount | grep <dir>; remount rw if needed).

Example fix

# before
dr-xr-xr-x rqlite:rqlite /var/lib/rqlite/backup
# after
chmod u+w /var/lib/rqlite/backup
# verify
sudo -u rqlite touch /var/lib/rqlite/backup/.probe && rm /var/lib/rqlite/backup/.probe
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(dir)
if err != nil || !info.IsDir() { return fmt.Errorf("not a directory: %s", dir) }
if info.Mode().Perm()&0o200 == 0 { return fmt.Errorf("directory not writable by owner: %s", dir) }

Prevention

When it happens

Trigger: os.OpenFile on <dir>/.touch fails because the process user lacks write permission on the directory, an immutable flag is set, or the write is blocked by security policy/SELinux/AppArmor.

Common situations: Directory owned by root but rqlited runs as the rqlite user; NFS mounts exported read-only or root-squashed; SELinux/AppArmor denials; backups directory made read-only after an incident.

Related errors


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