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

  1. Re-check that the --path directory still exists and is a readable directory at run time (ls -ld <path>)
  2. Check for external processes (cleanup jobs, volume remounts) mutating the directory while the tool runs
  3. Inspect audit logs (SELinux denials, auditd) if stat succeeds but open fails
  4. 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

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


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)