thanos-io/thanos · error

read meta of

Error message

read meta of %v

What it means

Wraps metadata.ReadFromDir failing after download, i.e. the downloaded block directory has no valid meta.json. ReadFromDir parses the JSON meta file; failures come from a missing meta.json or unparseable/corrupt JSON content in tmpDir.

Solutions

  1. Delete the stale temp dir (or let the command's os.RemoveAll run fresh) and retry the rewrite.
  2. Check meta.json exists and is valid in the object store: `thanos tools bucket inspect` or download meta.json manually.
  3. Free disk space / verify tmpDir is on a writable, non-full volume, then retry.

Example fix

// before (stale tmp dir)
TMPDIR=/data/thanos-rewrite
// after (fresh unique tmp dir per run)
thanos tools bucket rewrite --tmp.dir=/data/thanos-rewrite-$(date +%s) ...
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(filepath.Join(blockDir, "meta.json")); err != nil {
    return fmt.Errorf("meta.json missing in %s", blockDir)
}

Try / catch

meta, err := metadata.ReadFromDir(dir)
if err != nil {
    os.RemoveAll(dir) // clean stale partial download
    return errors.Wrapf(err, "read meta of %v", id)
}

Prevention

When it happens

Trigger: Download only partially completed (meta.json never fetched); meta.json corrupted in the object store; another rewrite run left a stale/partial block in the same tmpDir; disk filled and truncated the file.

Common situations: Shared tmpDir collisions when running two rewrite commands with the same temp dir; interrupted previous run leaving partial download; object store object corrupted; out-of-disk conditions.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at cmd/thanos/tools_bucket.go:1255

		if err := os.MkdirAll(tbc.tmpDir, os.ModePerm); err != nil {
			return err
		}

		ctx, cancel := context.WithCancel(context.Background())
		g.Add(func() error {
			chunkPool := chunkenc.NewPool()
			changeLog := compactv2.NewChangeLog(io.Discard)
			stubCounter := promauto.With(nil).NewCounter(prometheus.CounterOpts{})
			for _, id := range ids {
				// Delete series from block & modify.
				level.Info(logger).Log("msg", "downloading block", "source", id)
				if err := block.Download(ctx, logger, insBkt, id, filepath.Join(tbc.tmpDir, id.String())); err != nil {
					return errors.Wrapf(err, "download %v", id)
				}

				meta, err := metadata.ReadFromDir(filepath.Join(tbc.tmpDir, id.String()))
				if err != nil {
					return errors.Wrapf(err, "read meta of %v", id)
				}
				b, err := tsdb.OpenBlock(logutil.GoKitLogToSlog(logger), filepath.Join(tbc.tmpDir, id.String()), chunkPool, nil)
				if err != nil {
					return errors.Wrapf(err, "open block %v", id)
				}

				p := compactv2.NewProgressLogger(logger, int(b.Meta().Stats.NumSeries))
				newID := ulid.MustNew(ulid.Now(), rand.Reader)
				meta.ULID = newID
				meta.Thanos.Rewrites = append(meta.Thanos.Rewrites, metadata.Rewrite{
					Sources:          meta.Compaction.Sources,
					DeletionsApplied: deletions,
					RelabelsApplied:  relabels,
				})
				meta.Compaction.Sources = []ulid.ULID{newID}
				meta.Thanos.Source = metadata.BucketRewriteSource

				if err := os.MkdirAll(filepath.Join(tbc.tmpDir, newID.String()), os.ModePerm); err != nil {

View on GitHub (pinned to 35b8b99117)