thanos-io/thanos · error
opening tsdb directory
Error message
opening tsdb directory
What it means
The sidecar failed to open the local TSDB data directory (os.OpenRoot on conf.tsdb.path) when constructing the block shipper. This is a filesystem-level failure and prevents block upload from starting at all.
Solutions
- Point --tsdb.path at the actual Prometheus data directory (the one containing wal/ and block dirs).
- Ensure the directory exists and the sidecar's user has read access (check mounts in container deployments).
- Verify with ls -la <tsdb.path> as the same user the sidecar runs as.
- Confirm the Prometheus data volume is mounted before the sidecar starts.
Example fix
# before sidecar --tsdb.path=data ... # after sidecar --tsdb.path=/var/lib/prometheus ...
Defensive patterns
Strategy: validation
Validate before calling
stat, err := os.Stat(tsdbPath)
if err != nil || !stat.IsDir() { return fmt.Errorf("tsdb path %s missing", tsdbPath) } Try / catch
if err := run(); err != nil {
if os.IsNotExist(errors.Unwrap(err)) { /* fix --tsdb.path */ }
} Prevention
- Mount the Prometheus data volume into sidecar containers before startup.
- Verify --tsdb.path in deployment manifests with a pre-start check.
- Run the sidecar as a user with read access to the data dir.
When it happens
Trigger: os.OpenRoot(conf.tsdb.path) returns an error: the path given via --tsdb.path does not exist, is not a directory, or the process lacks read permission on it.
Common situations: --tsdb.path typo or default 'data/' used while Prometheus stores data elsewhere; sidecar running in a container without the Prometheus data volume mounted; permission mismatch between Prometheus (different uid) and the sidecar process.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- get content of limit configuration
- not uploading as no external labels are configured yet - is…
- found that Prometheus and Thanos use different paths for…
- WAL dir is not accessible. Is this dir a TSDB directory? If…
- Dir is not accessible.
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/458b9dfa6fd9fcea.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/sidecar.go:462
g.Add(func() error {
defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client")
promReadyTimeout := conf.prometheus.readyTimeout
extLabelsCtx, cancel := context.WithTimeout(ctx, promReadyTimeout)
defer cancel()
if err := runutil.Retry(2*time.Second, extLabelsCtx.Done(), func() error {
if m.Labels().Len() == 0 {
return errors.New("not uploading as no external labels are configured yet - is Prometheus healthy/reachable?")
}
return nil
}); err != nil {
return errors.Wrapf(err, "aborting as no external labels found after waiting %s", promReadyTimeout)
}
dataDir, err := os.OpenRoot(conf.tsdb.path)
if err != nil {
return errors.Wrap(err, "opening tsdb directory")
}
defer runutil.CloseWithLogOnErr(logger, dataDir, "tsdb directory")
s := shipper.New(
bkt,
dataDir,
shipper.WithLogger(logger),
shipper.WithRegisterer(reg),
shipper.WithSource(metadata.SidecarSource),
shipper.WithHashFunc(metadata.HashFunc(conf.shipper.hashFunc)),
shipper.WithMetaFileName(conf.shipper.metaFileName),
shipper.WithLabels(m.Labels),
shipper.WithUploadCompacted(conf.shipper.uploadCompacted),
shipper.WithAllowOutOfOrderUploads(conf.shipper.allowOutOfOrderUpload),
shipper.WithSkipCorruptedBlocks(conf.shipper.skipCorruptedBlocks),
shipper.WithUploadConcurrency(conf.shipper.uploadConcurrency),
)
View on GitHub (pinned to 35b8b99117)