thanos-io/thanos · error
unexpected meta file Thanos section version
Error message
unexpected meta file Thanos section version %d
What it means
Read rejects meta.json files whose thanos section version is not ThanosVersion1 (1). Note the message incorrectly reports m.Version (the TSDB version) instead of the Thanos version. After defaulting version 0 to ThanosVersion1 for backwards compatibility, any other value is rejected.
Solutions
- Inspect meta.json's "thanos"."version" field; only 0/1 are accepted by this reader.
- Upgrade Thanos to a version matching the block's thanos meta version.
- Rewrite the block's meta.json with a compatible writer (e.g. re-upload from source).
- If hand-edited, restore thanos.version to 1 (or remove it for compatibility default).
Example fix
// before (meta.json)
{"version":1,"thanos":{"version":2,...}}
// after
{"version":1,"thanos":{"version":1,...}} Defensive patterns
Strategy: validation
Validate before calling
var raw struct{ Thanos struct{ Version int `json:"version"` } `json:"thanos"` }
b, _ := os.ReadFile(filepath.Join(bdir, "meta.json"))
if json.Unmarshal(b, &raw) == nil {
if v := raw.Thanos.Version; v != 0 && v != 1 {
return fmt.Errorf("unsupported thanos meta version %d in %s", v, bdir)
}
} Type guard
func isThanosMetaV1(raw []byte) bool {
var m struct{ Thanos struct{ Version int `json:"version"` } `json:"thanos"` }
return json.Unmarshal(raw, &m) == nil && (m.Thanos.Version == 0 || m.Thanos.Version == 1)
} Try / catch
m, err := metadata.ReadFromDir(ctx, bdir)
if err != nil {
if strings.Contains(err.Error(), "unexpected meta file Thanos section version") {
logger.Log("msg", "block written by newer Thanos; upgrade required", "dir", bdir)
return nil
}
return err
} Prevention
- Run the same or newer Thanos version on readers as on writers.
- Check the thanos.version field when importing blocks from another deployment.
- Plan upgrades so blocks written after a meta format bump are never read by old binaries.
When it happens
Trigger: Calling Read on a meta.json whose "thanos.version" field is set to a value other than 0 or 1 (e.g. 2) — typically a block written by a newer Thanos with a bumped Thanos meta format.
Common situations: Older Thanos binary reading blocks produced by a newer Thanos that bumped thanos.version; hand-edited thanos section; corrupted meta.json.
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
- unexpected meta file version
- failed to parse the template
- failed to execute the template
- empty external labels are not allowed for Thanos block.
- read new meta
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/4cb8c175d8b9fdc9.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/metadata/meta.go:291
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)