thanos-io/thanos · error

unexpected meta file version

Error message

unexpected meta file version %d

What it means

Read rejects meta.json files whose TSDB version field is not TSDBVersion1 (1). This is a guard: the Thanos meta reader only understands Prometheus TSDB meta version 1 files, so any other version is treated as unreadable rather than misinterpreted.

Solutions

  1. Check meta.json's "version" field; it must be 1 for this reader.
  2. Regenerate the block with a compatible Prometheus/Thanos version (TSDB meta v1).
  3. Upgrade Thanos if the block was written by newer tooling that emits a newer meta version.
  4. Remove corrupted or hand-modified blocks and re-upload/re-sync from source.

Example fix

// before (meta.json)
{"version": 2, ...}
// after
{"version": 1, ...}
Defensive patterns

Strategy: validation

Validate before calling

var raw struct{ Version int `json:"version"` }
b, _ := os.ReadFile(filepath.Join(bdir, "meta.json"))
if json.Unmarshal(b, &raw) == nil && raw.Version != 1 {
    return fmt.Errorf("unsupported TSDB meta version %d in %s", raw.Version, bdir)
}

Type guard

func isTSDBMetaV1(raw []byte) bool {
    var m struct{ Version int `json:"version"` }
    return json.Unmarshal(raw, &m) == nil && m.Version == 1
}

Try / catch

m, err := metadata.ReadFromDir(ctx, bdir)
if err != nil {
    if strings.Contains(err.Error(), "unexpected meta file version") {
        // skip or quarantine incompatible block
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling Read (or ReadFromDir) on a meta.json where the top-level "version" field is not 1 — e.g. a future Prometheus format or a manually crafted/edited file with a different version.

Common situations: Reading blocks written by a newer Prometheus/Thanos that bumped the meta version; hand-edited meta.json; blocks produced by incompatible tooling; file corruption changing the version field.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at pkg/block/metadata/meta.go:281

func ReadFromDir(dir string) (*Meta, error) {
	f, err := os.Open(filepath.Join(dir, filepath.Clean(MetaFilename)))
	if err != nil {
		return nil, err
	}
	return Read(f)
}

// Read the block meta from the given reader.
func Read(rc io.ReadCloser) (_ *Meta, err error) {
	defer runutil.ExhaustCloseWithErrCapture(&err, rc, "close meta JSON")

	var m Meta
	if err = json.NewDecoder(rc).Decode(&m); err != nil {
		return nil, err
	}

	if m.Version != TSDBVersion1 {
		return nil, errors.Errorf("unexpected meta file version %d", m.Version)
	}

	version := m.Thanos.Version
	if version == 0 {
		// For compatibility.
		version = ThanosVersion1
	}

	if version != ThanosVersion1 {
		return nil, errors.Errorf("unexpected meta file Thanos section version %d", m.Version)
	}

	if m.Thanos.Labels == nil {
		// To avoid extra nil checks, allocate map here if empty.
		m.Thanos.Labels = make(map[string]string)
	}
	return &m, nil
}

View on GitHub (pinned to 35b8b99117)