thanos-io/thanos · error

open data dir

Error message

open data dir

What it means

When sidecar upload is enabled, runRule opens the rule evaluator's data directory with os.OpenRoot(conf.dataDir) to hand it to the shipper. If the directory cannot be opened (missing, not a directory, permission denied), the error is wrapped as "open data dir" and startup aborts.

Solutions

  1. Ensure --data-dir exists and is a writable directory (mkdir -p and chown to the process user).
  2. Mount a persistent volume at the dataDir path in your container spec.
  3. Fix the --data-dir flag value if it points to a file or a typo'd path.
  4. Remove the read-only flag from the volume mount, or disable shipping if upload is not intended.

Example fix

// before
thanos rule --data-dir=/mnt/missing/rule --objstore-bucket=thanos
// after
mkdir -p /var/thanos/rule && thanos rule --data-dir=/var/thanos/rule --objstore-bucket=thanos
Defensive patterns

Strategy: validation

Validate before calling

test -d "$DATA_DIR" || mkdir -p "$DATA_DIR"; test -w "$DATA_DIR" || { echo "data dir not writable"; exit 1; }

Prevention

When it happens

Trigger: Running thanos rule with --objstore-bucket (shipper enabled) where --data-dir does not exist and cannot be created/opened, points to a file, or the process lacks read permission on it.

Common situations: Forgetting to mount the persistent volume that holds --data-dir in Kubernetes; dataDir typo like /var/thanos/ruel; volume mounted read-only while the shipper needs write access.

Related errors


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

Appendix: source

Thrown at cmd/thanos/rule.go:901

	}

	confContentYaml, err := conf.objStoreConfig.Content()
	if err != nil {
		return err
	}

	if len(confContentYaml) > 0 {
		// The background shipper continuously scans the data directory and uploads
		// new blocks to Google Cloud Storage or an S3-compatible storage service.
		bkt, err := client.NewBucket(logger, confContentYaml, component.Rule.String(), nil)
		if err != nil {
			return err
		}
		bkt = objstoretracing.WrapWithTraces(objstore.WrapWithMetrics(bkt, extprom.WrapRegistererWithPrefix("thanos_", reg), bkt.Name()))

		dataDir, err := os.OpenRoot(conf.dataDir)
		if err != nil {
			return errors.Wrap(err, "open data dir")
		}

		s := shipper.New(
			bkt,
			dataDir,
			shipper.WithLogger(logger),
			shipper.WithRegisterer(reg),
			shipper.WithSource(metadata.RulerSource),
			shipper.WithHashFunc(metadata.HashFunc(conf.shipper.hashFunc)),
			shipper.WithMetaFileName(conf.shipper.metaFileName),
			shipper.WithLabels(func() labels.Labels { return conf.lset }),
			shipper.WithAllowOutOfOrderUploads(conf.shipper.allowOutOfOrderUpload),
			shipper.WithSkipCorruptedBlocks(conf.shipper.skipCorruptedBlocks),
			shipper.WithUploadConcurrency(conf.shipper.uploadConcurrency),
		)

		ctx, cancel := context.WithCancel(context.Background())

View on GitHub (pinned to 35b8b99117)