thanos-io/thanos · error

WAL dir is not accessible. Is this dir a TSDB directory? If…

Error message

WAL dir is not accessible. Is this dir a TSDB directory? If yes it is shared with TSDB?

What it means

IsWALDirAccessible checks that <dir>/wal exists and is a directory (i.e. the path looks like a live Prometheus TSDB directory). When os.Stat fails (missing path, permission problem), the stat error is wrapped with this message explaining the directory is not a usable TSDB/WAL directory.

Solutions

  1. Point --tsdb.path at the real Prometheus --storage.tsdb.path
  2. Verify the wal/ subdirectory exists: ls <dir>/wal
  3. Fix filesystem permissions so the sidecar user can read the TSDB dir
  4. Ensure Prometheus is running and has initialized its data directory before the sidecar
  5. Check volume mounts in containers/Kubernetes (correct PVC attached)

Example fix

// before
thanos sidecar --tsdb.path=/data
// after: verify dir first
ls /data/wal || echo "not a TSDB dir"
thanos sidecar --tsdb.path=/prometheus   # where Prometheus stores data (contains wal/)
Defensive patterns

Strategy: validation

Validate before calling

func walDirLooksValid(dir string) error {
    info, err := os.Stat(filepath.Join(dir, "wal"))
    if err != nil {
        return fmt.Errorf("%s/wal not statable: %w", dir, err)
    }
    if !info.IsDir() {
        return fmt.Errorf("%s/wal is not a directory", dir)
    }
    return nil
}

Try / catch

if err := promclient.IsWALDirAccessible(tsdbPath); err != nil {
    log.Fatalf("invalid --tsdb.path: %v", err)
}

Prevention

When it happens

Trigger: os.Stat(filepath.Join(dir, "wal")) returns an error — the 'wal' subdirectory does not exist under the given dir, or the process lacks permission to stat it. Called from runSidecar when validating --tsdb.path and from an anonymous caller (e.g. tools/bucket verification of a local dir).

Common situations: Thanos sidecar started with --tsdb.path pointing at a directory that is not the Prometheus data dir (empty volume, wrong mount), Prometheus not yet started so wal/ is absent, or the container lacks read access to the mounted path.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/bfcb7cdd36444d96. Report an issue: GitHub.

Appendix: source

Thrown at pkg/promclient/promclient.go:156

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, resp.StatusCode, errors.Wrap(err, "read body")
	}
	if resp.StatusCode/100 != 2 {
		return nil, resp.StatusCode, errors.Errorf("expected 2xx response, got %d. Body: %v", resp.StatusCode, string(body))
	}
	return body, resp.StatusCode, nil
}

// IsWALDirAccessible returns no error if WAL dir can be found. This helps to tell
// if we have access to Prometheus TSDB directory.
func IsWALDirAccessible(dir string) error {
	const errMsg = "WAL dir is not accessible. Is this dir a TSDB directory? If yes it is shared with TSDB?"

	f, err := os.Stat(filepath.Join(dir, "wal"))
	if err != nil {
		return errors.Wrap(err, errMsg)
	}

	if !f.IsDir() {
		return errors.New(errMsg)
	}

	return nil
}

// IsDirAccessible returns no error if dir can be found.
func IsDirAccessible(dir string) error {
	const errMsg = "Dir is not accessible."

	f, err := os.Stat(dir)
	if err != nil {
		return errors.Wrap(err, errMsg)
	}

View on GitHub (pinned to 35b8b99117)