{"record":{"id":"d9cf69670688191d","repo":"thanos-io/thanos","slug":"open-block","errorCode":null,"errorMessage":"open block","messagePattern":"open block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/block/index.go","lineNumber":434,"sourceCode":"\tif len(ignoreChkFns) == 0 {\n\t\treturn resid, errors.New(\"no ignore chunk function specified\")\n\t}\n\n\tbdir := filepath.Join(dir, id.String())\n\tentropy := rand.New(rand.NewSource(time.Now().UnixNano()))\n\tresid = ulid.MustNew(ulid.Now(), entropy)\n\n\tmeta, err := metadata.ReadFromDir(bdir)\n\tif err != nil {\n\t\treturn resid, errors.Wrap(err, \"read meta file\")\n\t}\n\tif meta.Thanos.Downsample.Resolution > 0 {\n\t\treturn resid, errors.New(\"cannot repair downsampled block\")\n\t}\n\n\tb, err := tsdb.OpenBlock(logutil.GoKitLogToSlog(logger), bdir, nil, nil)\n\tif err != nil {\n\t\treturn resid, errors.Wrap(err, \"open block\")\n\t}\n\tdefer runutil.CloseWithErrCapture(&err, b, \"repair block reader\")\n\n\tindexr, err := b.Index()\n\tif err != nil {\n\t\treturn resid, errors.Wrap(err, \"open index\")\n\t}\n\tdefer runutil.CloseWithErrCapture(&err, indexr, \"repair index reader\")\n\n\tchunkr, err := b.Chunks()\n\tif err != nil {\n\t\treturn resid, errors.Wrap(err, \"open chunks\")\n\t}\n\tdefer runutil.CloseWithErrCapture(&err, chunkr, \"repair chunk reader\")\n\n\tresdir := filepath.Join(dir, resid.String())\n\n\tchunkw, err := chunks.NewWriter(filepath.Join(resdir, ChunksDirname))","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/index.go#L416-L452","documentation":"block.Repair wraps the error from tsdb.OpenBlock, which loads the block's index and chunks files into an immutable TSDB block. This fires when the block directory is unreadable, files are missing/corrupt, or meta.json is inconsistent with the on-disk data (e.g. version mismatch). The original tsdb error is wrapped as 'open block: <cause>'.","triggerScenarios":"Repair called on a block dir where chunks/ or index files are missing, truncated, or corrupted (the very corruption Repair is meant to fix can be too severe to open); meta.json missing or invalid; disk I/O or permission errors; tsdb block format version not supported by this binary.","commonSituations":"Repairing a block pulled from object storage that was truncated during download; running repair after a crashed compaction left partial files; version skew where an older Thanos/tsdb tries to open blocks written by a newer Prometheus; wrong block directory passed (contains no block).","solutions":["Inspect the wrapped cause: verify the block dir contains meta.json, index, and chunks/ files and that they are not zero-length.","Re-download or re-upload the block from object storage and retry; compare ETag/checksum to detect truncation.","If index is corrupt beyond opening, delete the block and re-upload/re-compact from the source Prometheus.","Check tsdb/Prometheus version compatibility; upgrade Thanos so it can open blocks written by newer Prometheus."],"exampleFix":"// before\nif _, err := block.RepairIssue347(ctx, logger, dir, id, source); err != nil {\n    return err // opaque 'open block: ...' on truncated block\n}\n// after\nbdir := filepath.Join(dir, id.String())\nfor _, f := range []string{\"meta.json\", \"index\"} {\n    if fi, err := os.Stat(filepath.Join(bdir, f)); err != nil || fi.Size() == 0 {\n        return fmt.Errorf(\"block %s missing/empty %s: re-download\", id, f)\n    }\n}","handlingStrategy":"try-catch","validationCode":"bdir := filepath.Join(dir, id.String())\nfor _, f := range []string{\"meta.json\", \"index\"} {\n    if fi, err := os.Stat(filepath.Join(bdir, f)); err != nil || fi.Size() == 0 {\n        return fmt.Errorf(\"block %s: %s missing or empty\", id, f)\n    }\n}\nif _, err := metadata.ReadFromDir(bdir); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"resid, err := block.RepairIssue347(ctx, logger, dir, id, source)\nif err != nil && strings.Contains(err.Error(), \"open block\") {\n    // not retryable in place: re-fetch the block, then retry once\n    if rerr := redownloadBlock(ctx, bucket, dir, id); rerr != nil {\n        return resid, fmt.Errorf(\"open block failed and re-download failed: %w\", rerr)\n    }\n    resid, err = block.RepairIssue347(ctx, logger, dir, id, source)\n}","preventionTips":["Verify checksums/sizes after downloading blocks from object storage before repairing.","Never repair blocks still being written by Prometheus or a running compaction.","Keep Thanos/tsdb versions aligned with the Prometheus version that wrote the blocks.","Run repair on a copy of the block, not the only copy."],"tags":["thanos","tsdb","corruption","file-open-failed"],"backgroundTag":"file-open-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"}