{"record":{"id":"1c2c3c2991b89fb2","repo":"thanos-io/thanos","slug":"empty-chunks-for-series-d","errorCode":null,"errorMessage":"empty chunks for series %d","messagePattern":"empty chunks for series (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/index.go","lineNumber":304,"sourceCode":"\t\t\treturn stats, errors.Errorf(\"series %v out of order; previous %v\", lset, prevLset)\n\t\t}\n\t\tvar l0 *labels.Label\n\t\tlset.Range(func(l labels.Label) {\n\t\t\tif l0 != nil {\n\t\t\t\tif l.Name < l0.Name {\n\t\t\t\t\tstats.OutOfOrderLabels++\n\t\t\t\t\tlevel.Warn(logger).Log(\"msg\",\n\t\t\t\t\t\t\"out-of-order label set: known bug in Prometheus 2.8.0 and below\",\n\t\t\t\t\t\t\"labelset\", lset.String(),\n\t\t\t\t\t\t\"series\", fmt.Sprintf(\"%d\", id),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tl0 = &l\n\t\t})\n\n\t\tif len(chks) == 0 {\n\t\t\treturn stats, errors.Errorf(\"empty chunks for series %d\", id)\n\t\t}\n\n\t\tooo := 0\n\t\tseriesLifeTimeMs := int64(0)\n\t\t// Per chunk in series.\n\t\tfor i, c := range chks {\n\t\t\tstats.TotalChunks++\n\n\t\t\tchkDur := c.MaxTime - c.MinTime\n\t\t\tseriesLifeTimeMs += chkDur\n\t\t\tchunkDuration.Add(chkDur)\n\t\t\tif chkDur == 0 {\n\t\t\t\tstats.SingleSampleChunks++\n\t\t\t}\n\n\t\t\t// Approximate size.\n\t\t\tif i < len(chks)-2 {\n\t\t\t\tsgmIndex, chkStart := chunks.BlockChunkRef(c.Ref).Unpack()","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/index.go#L286-L322","documentation":"Every series must reference at least one chunk in the index. GatherIndexHealthStats errors with \"empty chunks for series %d\" when a decoded series has zero chunks. Such a series would be invisible to queries, so the index is considered corrupt.","triggerScenarios":"r.Series returns successfully but the chunk meta slice is empty — caused by a damaged index chunk section, truncation cutting chunk metas off, or buggy index writers.","commonSituations":"Blocks truncated during upload/download, storage corruption cutting the index short, blocks produced by experimental/broken tooling, verification after incidents.","solutions":["Restore the block from object storage or backup","Run offline compaction to rebuild the index from the chunk data if chunks are intact","Use block.Repair to drop incomplete/outside data where applicable","Delete the corrupt block and let it re-sync or be tombstoned"],"exampleFix":"// before\nstats, err := block.GatherIndexHealthStats(ctx, bdir) // empty chunks for series 987\n// after\nif err := block.VerifyIndex(ctx, bdir, 1); err != nil {\n    logger.Log(\"msg\", \"dropping corrupt block\", \"err\", err)\n    os.RemoveAll(bdir)\n}","handlingStrategy":"try-catch","validationCode":"if err := block.VerifyIndex(ctx, bdir, 1); err != nil {\n    return fmt.Errorf(\"unhealthy block %s, refusing to use: %w\", bdir, err)\n}","typeGuard":null,"tryCatchPattern":"stats, err := block.GatherIndexHealthStats(ctx, bdir)\nif err != nil && strings.Contains(err.Error(), \"empty chunks for series\") {\n    return fmt.Errorf(\"index chunk section truncated in %s: %w\", bdir, err)\n}","preventionTips":["Validate block size against meta.json stats after download","Enable integrity checksums in object storage","Verify every block before loading/serving","Drop blocks that fail health checks instead of retrying"],"tags":["corruption","index","chunks"],"backgroundTag":"internal-invariant-violation","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"}