{"record":{"id":"8634acc201a3df40","repo":"thanos-io/thanos","slug":"unmarshal-meta-json-for-block-s","errorCode":null,"errorMessage":"unmarshal meta.json for block %s","messagePattern":"unmarshal meta\\.json for block (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/block.go","lineNumber":295,"sourceCode":"\n// DownloadMeta downloads only meta file from bucket by block ID.\n// TODO(bwplotka): Differentiate between network error & partial upload.\nfunc DownloadMeta(ctx context.Context, logger log.Logger, bkt objstore.Bucket, id ulid.ULID) (metadata.Meta, error) {\n\trc, err := bkt.Get(ctx, path.Join(id.String(), MetaFilename))\n\tif err != nil {\n\t\treturn metadata.Meta{}, errors.Wrapf(err, \"meta.json bkt get for %s\", id.String())\n\t}\n\tdefer runutil.CloseWithLogOnErr(logger, rc, \"download meta bucket client\")\n\n\tvar m metadata.Meta\n\n\tobj, err := io.ReadAll(rc)\n\tif err != nil {\n\t\treturn metadata.Meta{}, errors.Wrapf(err, \"read meta.json for block %s\", id.String())\n\t}\n\n\tif err = json.Unmarshal(obj, &m); err != nil {\n\t\treturn metadata.Meta{}, errors.Wrapf(err, \"unmarshal meta.json for block %s\", id.String())\n\t}\n\n\treturn m, nil\n}\n\nfunc IsBlockMetaFile(path string) bool {\n\treturn filepath.Base(path) == MetaFilename\n}\n\nfunc IsBlockDir(path string) (id ulid.ULID, ok bool) {\n\tid, err := ulid.Parse(filepath.Base(path))\n\treturn id, err == nil\n}\n\n// GetSegmentFiles returns list of segment files for given block. Paths are relative to the chunks directory.\n// In case of errors, nil is returned.\nfunc GetSegmentFiles(blockDir string) []string {\n\tfiles, err := os.ReadDir(filepath.Join(blockDir, ChunksDirname))","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/block.go#L277-L313","documentation":"DownloadMeta successfully read meta.json bytes from object storage but json.Unmarshal could not decode them into metadata.Meta. This means the stored meta.json is corrupt, empty, or not valid JSON matching the metadata schema.","triggerScenarios":"io.ReadAll succeeded but json.Unmarshal(obj, &m) returned an error — malformed JSON, truncated upload, empty object, or meta.json written by an incompatible producer.","commonSituations":"Partially written meta.json from a failed upload; a manually edited/deleted-then-recreated meta.json; object corrupted by a buggy uploader or storage backend; block written by a different Thanos/TSDB version with incompatible fields.","solutions":["Inspect the meta.json object in the bucket (cat it via mc/aws s3 cp) to see the corruption.","Delete the corrupted block from the bucket if it's not needed, or re-upload a valid meta.json.","Verify the uploader that wrote the block (network interruption during upload?).","Check for storage backend corruption and restore from backup if blocks are broadly affected."],"exampleFix":"// before\nif err = json.Unmarshal(obj, &m); err != nil {\n\treturn metadata.Meta{}, errors.Wrapf(err, \"unmarshal meta.json for block %s\", id.String())\n}\n// after\nif err = json.Unmarshal(obj, &m); err != nil {\n\treturn metadata.Meta{}, errors.Wrapf(err, \"unmarshal meta.json for block %s (len=%d, body=%q)\", id.String(), len(obj), string(obj))\n}","handlingStrategy":"try-catch","validationCode":"rc, err := bkt.Get(ctx, path.Join(id.String(), metadata.MetaFilename))\nif err != nil { return err }\ndefer rc.Close()\nobj, err := io.ReadAll(rc)\nif err != nil { return err }\nif !json.Valid(obj) {\n\treturn fmt.Errorf(\"meta.json for block %s is not valid JSON (len=%d)\", id, len(obj))\n}","typeGuard":"func isValidMetaJSON(b []byte) bool {\n\tif len(b) == 0 || !json.Valid(b) { return false }\n\tvar m metadata.Meta\n\treturn json.Unmarshal(b, &m) == nil\n}","tryCatchPattern":"m, err := block.DownloadMeta(ctx, logger, bkt, id)\nif err != nil && strings.Contains(err.Error(), \"unmarshal meta.json\") {\n\t// corrupted meta: quarantine or delete the block, do not retry\n\treturn deleteCorruptBlock(ctx, bkt, id)\n}","preventionTips":["Validate meta.json with json.Valid before trusting any downloaded block.","Don't manually edit meta.json objects in the bucket.","Ensure uploads of meta.json are atomic/complete (verify after upload).","Run Thanos tools bucket verify periodically to catch corrupted blocks."],"tags":["json","object-storage","thanos"],"backgroundTag":"json-unmarshal-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"}