{"record":{"id":"05e96465b90ee3da","repo":"thanos-io/thanos","slug":"cannot-repair-downsampled-block","errorCode":null,"errorMessage":"cannot repair downsampled block","messagePattern":"cannot repair downsampled block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/index.go","lineNumber":429,"sourceCode":"// - all \"complete\" outsiders (they will not accessed anyway)\n// - removes all near \"complete\" outside chunks introduced by https://github.com/prometheus/tsdb/issues/347.\n// Fixable inconsistencies are resolved in the new block.\n// TODO(bplotka): https://github.com/thanos-io/thanos/issues/378.\nfunc Repair(ctx context.Context, logger log.Logger, dir string, id ulid.ULID, source metadata.SourceType, ignoreChkFns ...ignoreFnType) (resid ulid.ULID, err error) {\n\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}","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/index.go#L411-L447","documentation":"block.Repair refuses to run on a block whose metadata declares a non-zero Thanos downsample resolution. Repair rewrites raw (resolution=0) blocks to fix tsdb#347 index corruption; downsampled blocks have aggregated data, so the repair invariants and ignore functions do not apply to them. The check is done right after reading meta.json from the block directory.","triggerScenarios":"Calling block.Repair (directly or via RepairIssue347/repairIndex) on a block directory whose meta.json has thanos.downsample.resolution > 0 — i.e. any 5m or 1h downsampled block.","commonSituations":"Running the issue-347 repair tooling against a whole bucket/dir without filtering by resolution; pointing repair at a compacted/downsampled block produced by the thanos compact downscoping; scripting repair over every ULID in a data dir that contains both raw and downsampled blocks.","solutions":["Check the block's meta.json before calling Repair and skip blocks with thanos.downsample.resolution > 0.","Only invoke repair on raw blocks uploaded by the Prometheus sidecar (source=sidecar/compactor with resolution 0).","If the downsampled block is actually broken, delete it and let the Thanos compactor regenerate it from the raw block instead of repairing it."],"exampleFix":"// before\nfor _, id := range ids {\n    if _, err := block.Repair(ctx, logger, dir, id, source, block.IgnoreCompleteOutsideChunk); err != nil {\n        return err // fails on downsampled blocks\n    }\n}\n// after\nfor _, id := range ids {\n    meta, err := metadata.ReadFromDir(filepath.Join(dir, id.String()))\n    if err != nil {\n        return err\n    }\n    if meta.Thanos.Downsample.Resolution > 0 {\n        continue // skip downsampled blocks\n    }\n    if _, err := block.Repair(ctx, logger, dir, id, source, block.IgnoreCompleteOutsideChunk); err != nil {\n        return err\n    }\n}","handlingStrategy":"validation","validationCode":"meta, err := metadata.ReadFromDir(filepath.Join(dir, id.String()))\nif err != nil {\n    return err\n}\nif meta.Thanos.Downsample.Resolution > 0 {\n    return fmt.Errorf(\"block %s is downsampled (resolution=%d); skip repair\", id, meta.Thanos.Downsample.Resolution)\n}","typeGuard":"func isRawBlock(meta *metadata.Meta) bool {\n    return meta != nil && meta.Thanos.Downsample.Resolution == 0\n}","tryCatchPattern":"resid, err := block.RepairIssue347(ctx, logger, dir, id, source)\nif err != nil {\n    if strings.Contains(err.Error(), \"cannot repair downsampled block\") {\n        logger.Log(\"msg\", \"skipping downsampled block\", \"block\", id)\n        return id, nil // expected condition, not a failure\n    }\n    return id, err\n}","preventionTips":["Always read meta.json and branch on thanos.downsample.resolution before any repair call.","Enumerate repair candidates via bucket inspection filtered on resolution==0.","Document that Repair is a raw-block-only tool in any operator runbook."],"tags":["thanos","block-repair","downsampling","guard-error"],"backgroundTag":"unsupported-operation","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"}