{"record":{"id":"e4d279df44aeb8f6","repo":"thanos-io/thanos","slug":"gather-index-issues-s","errorCode":null,"errorMessage":"gather index issues %s","messagePattern":"gather index issues (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/verifier/index_issue.go","lineNumber":139,"sourceCode":"\t\treturn errors.Wrapf(err, \"upload of %s failed\", resid)\n\t}\n\n\tlevel.Info(ctx.Logger).Log(\"msg\", \"safe deleting broken block\", \"id\", id, \"issue\")\n\tif err := BackupAndDeleteDownloaded(ctx, filepath.Join(dir, id.String()), id); err != nil {\n\t\treturn errors.Wrapf(err, \"safe deleting old block %s failed\", id)\n\t}\n\n\treturn nil\n}\n\nfunc verifyIndex(ctx Context, id ulid.ULID, dir string, meta *metadata.Meta) (stats block.HealthStats, err error) {\n\tif err := objstore.DownloadFile(ctx, ctx.Logger, ctx.Bkt, path.Join(id.String(), block.IndexFilename), filepath.Join(dir, block.IndexFilename)); err != nil {\n\t\treturn stats, errors.Wrapf(err, \"download index file %s\", path.Join(id.String(), block.IndexFilename))\n\t}\n\n\tstats, err = block.GatherIndexHealthStats(ctx, ctx.Logger, filepath.Join(dir, block.IndexFilename), meta.MinTime, meta.MaxTime)\n\tif err != nil {\n\t\treturn stats, errors.Wrapf(err, \"gather index issues %s\", id)\n\t}\n\n\tlevel.Debug(ctx.Logger).Log(\"stats\", fmt.Sprintf(\"%+v\", stats), \"id\", id)\n\n\treturn stats, stats.AnyErr()\n}\n","sourceCodeStart":121,"sourceCodeEnd":146,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/verifier/index_issue.go#L121-L146","documentation":"After downloading, verifyIndex calls block.GatherIndexHealthStats to scan the index for corruptions (series outside chunk bounds, duplicate postings, issue-347 style defects); any error is wrapped as \"gather index issues %s\". This means the index health analysis itself could not complete, distinct from stats.AnyErr() which reports the found defects.","triggerScenarios":"GatherIndexHealthStats errors while parsing the downloaded index: truncated or unreadable index file on local disk, unsupported/invalid index format, or an I/O error reading the local file.","commonSituations":"Index file corrupted in the bucket so it cannot even be parsed; disk full in the work dir corrupting the download; extremely old index format not understood by this Thanos version.","solutions":["Read the wrapped cause to see whether it's a parse, format, or I/O error.","Re-download with a fresh work directory to rule out local corruption.","If the index is truly unreadable, treat the block as corrupt: back it up and delete it, or restore from backup.","Upgrade Thanos if the index format is newer than the tool supports."],"exampleFix":"// before: reusing a work dir with a truncated index file\nworkDir := \"./work\"\n// after: fresh temp dir per verification run\nworkDir, _ := os.MkdirTemp(\"\", \"verifier-\")\ndefer os.RemoveAll(workDir)","handlingStrategy":"try-catch","validationCode":"// ensure the downloaded index is non-empty and readable before analysis\nfi, err := os.Stat(filepath.Join(dir, \"index\"))\nif err != nil || fi.Size() == 0 { return fmt.Errorf(\"index file missing/empty locally\") }","typeGuard":null,"tryCatchPattern":"if err := verify.VerifyIssue(...); err != nil {\n    if strings.Contains(err.Error(), \"gather index issues\") {\n        // index unparseable: re-download with fresh work dir or treat block as corrupt\n    }\n}","preventionTips":["Use a clean work directory per run to avoid locally truncated files","Monitor temp-volume free space during verification","Run a Thanos version that supports the blocks' index format"],"tags":["go","index","corruption","thanos"],"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"}