{"record":{"id":"532dcaabc02edc2d","repo":"thanos-io/thanos","slug":"read-new-meta","errorCode":null,"errorMessage":"read new meta","messagePattern":"read new meta","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/metadata/meta.go","lineNumber":181,"sourceCode":"type File struct {\n\tRelPath string `json:\"rel_path\"`\n\t// SizeBytes is optional (e.g meta.json does not show size).\n\tSizeBytes int64 `json:\"size_bytes,omitempty\"`\n\n\t// Hash is an optional hash of this file. Used for potentially avoiding an extra download.\n\tHash *ObjectHash `json:\"hash,omitempty\"`\n}\n\ntype ThanosDownsample struct {\n\tResolution int64 `json:\"resolution\"`\n}\n\n// InjectThanos sets Thanos meta to the block meta JSON and saves it to the disk.\n// NOTE: It should be used after writing any block by any Thanos component, otherwise we will miss crucial metadata.\nfunc InjectThanos(logger log.Logger, bdir string, meta Thanos, downsampledMeta *tsdb.BlockMeta) (*Meta, error) {\n\tnewMeta, err := ReadFromDir(bdir)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"read new meta\")\n\t}\n\tnewMeta.Thanos = meta\n\n\t// While downsampling we need to copy original compaction.\n\tif downsampledMeta != nil {\n\t\tnewMeta.Compaction = downsampledMeta.Compaction\n\t}\n\n\tif err := newMeta.WriteToDir(logger, bdir); err != nil {\n\t\treturn nil, errors.Wrap(err, \"write new meta\")\n\t}\n\n\treturn newMeta, nil\n}\n\n// GroupKey returns a unique identifier for the compaction group the block belongs to.\n// It considers the downsampling resolution and the block's labels.\nfunc (m *Thanos) GroupKey() string {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/metadata/meta.go#L163-L199","documentation":"InjectThanos wraps any failure from ReadFromDir, which parses the meta.json inside a TSDB block directory, before attaching Thanos metadata. It means the block's meta.json could not be read or decoded, so the Thanos section cannot be injected. The library throws this because writing a block without valid metadata would leave an unusable block.","triggerScenarios":"Calling InjectThanos on a directory (bdir) that has no meta.json, a corrupt/truncated meta.json, malformed JSON, or a directory that does not exist after block creation.","commonSituations":"Block creation failed or was interrupted so meta.json was never written; passing the wrong path (e.g. the bucket root instead of the block dir); meta.json deleted or corrupted by concurrent tooling; filesystem errors (permissions, disk full).","solutions":["Verify bdir is the actual block directory and contains a readable meta.json before calling InjectThanos.","Check that the block write (e.g. tsdb block creation) completed successfully before injecting Thanos meta.","Inspect the wrapped error (permissions, JSON decode) and fix the underlying cause.","Re-create the block if meta.json is corrupt or missing."],"exampleFix":"// before\nmeta, err := InjectThanos(logger, bucketRoot, thanosMeta, nil) // wrong dir\n// after\nmeta, err := InjectThanos(logger, filepath.Join(bucketRoot, blockID.String()), thanosMeta, nil)","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(filepath.Join(bdir, \"meta.json\")); err != nil {\n    return fmt.Errorf(\"block dir %s has no meta.json: %w\", bdir, err)\n}","typeGuard":"func hasMetaJSON(bdir string) bool {\n    fi, err := os.Stat(filepath.Join(bdir, \"meta.json\"))\n    return err == nil && !fi.IsDir()\n}","tryCatchPattern":"meta, err := InjectThanos(logger, bdir, thanosMeta, nil)\nif err != nil {\n    if strings.Contains(err.Error(), \"read new meta\") {\n        logger.Log(\"msg\", \"meta.json missing/corrupt; re-creating block\", \"dir\", bdir, \"err\", err)\n        return nil\n    }\n    return err\n}","preventionTips":["Always call InjectThanos immediately after a successful block write on the exact block dir.","Stat meta.json before injecting to fail fast with a clear message.","Never pass a parent or bucket-root path instead of the block directory."],"tags":["go","metadata","file-read-failed"],"backgroundTag":"file-read-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}