thanos-io/thanos · error
unable to open tbc directory
Error message
unable to open tbc directory
What it means
This error is returned when os.OpenRoot(tbc.path) fails after the bucket client was successfully created. OpenRoot opens the local directory as a rooted filesystem handle used by the shipper; failure typically means the directory does not exist or is inaccessible at open time. The command closes the bucket client and aborts the upload.
Solutions
- Re-check that the --path directory still exists and is a readable directory at run time (ls -ld <path>)
- Check for external processes (cleanup jobs, volume remounts) mutating the directory while the tool runs
- Inspect audit logs (SELinux denials, auditd) if stat succeeds but open fails
- Re-run the command once the directory is restored; earlier checks passed so the config itself is fine
Defensive patterns
Strategy: try-catch
Validate before calling
info, err := os.Stat(path)
if err != nil || !info.IsDir() {
return fmt.Errorf("directory %q must exist and be a directory before sync", path)
} Try / catch
if _, err := os.OpenRoot(path); err != nil {
logger.Error(err, "cannot open data directory; check it still exists and is not being remounted")
return err
} Prevention
- Avoid running uploads while cleanup jobs or volume rotations touch the data directory
- Use stable absolute paths, not volatile symlinks
- Check audit/SELinux logs when stat succeeds but open fails
- Re-run after transient failures; earlier stages (stat, config, bucket) already validated
When it happens
Trigger: The --path directory was deleted or renamed between the earlier IsDirAccessible check and OpenRoot; permission changed; or (on older thanos versions using ioutil.TempDir-style open) the path is a file rather than a directory.
Common situations: Race with a cleanup job removing the data dir; running the command while a deployment remounts or rotates the volume; SELinux/AppArmor denying directory open despite stat succeeding; pointing at a symlink whose target was removed.
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
- unable to access path
- failed to parse template
- failed to execute template
- failed to parse the template
- failed to execute the template
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/12a47d71a35b357f.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/tools_bucket.go:1491
return errors.Wrapf(err, "unable to access path '%s'", tbc.path)
}
confContentYaml, err := objStoreConfig.Content()
if err != nil {
return errors.Wrap(err, "unable to parse objstore config")
}
bkt, err := client.NewBucket(logger, confContentYaml, component.Upload.String(), nil)
if err != nil {
return errors.Wrap(err, "unable to create bucket")
}
bkt = objstoretracing.WrapWithTraces(objstore.WrapWithMetrics(bkt, extprom.WrapRegistererWithPrefix("thanos_", reg), bkt.Name()))
tbcDir, err := os.OpenRoot(tbc.path)
if err != nil {
runutil.CloseWithLogOnErr(logger, bkt, "bucket client")
return errors.Wrap(err, "unable to open tbc directory")
}
s := shipper.New(
bkt,
tbcDir,
shipper.WithLogger(logger),
shipper.WithRegisterer(reg),
shipper.WithSource(metadata.BucketUploadSource),
shipper.WithMetaFileName(shipper.DefaultMetaFilename),
shipper.WithLabels(func() labels.Labels { return lset }),
shipper.WithUploadCompacted(tbc.uploadCompacted),
shipper.WithUploadConcurrency(tbc.uploadConcurrency),
)
ctx, cancel := context.WithCancel(context.Background())
g.Add(func() error {
defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client")
defer runutil.CloseWithLogOnErr(logger, tbcDir, "tbc directory")View on GitHub (pinned to 35b8b99117)