thanos-io/thanos · error
plan compaction
Error message
plan compaction
What it means
The compaction planner (cg.planner.Plan) failed while computing which blocks should be compacted in this pass. Planning walks the block metadata and compaction levels; an error here means plan construction itself failed, before any data was downloaded or modified. This is a fatal error for the compaction iteration.
Solutions
- Inspect the wrapped inner error to identify which planner/extension failed
- Disable custom compaction extensions and re-run with the DefaultPlanner
- Run 'thanos tools bucket verify' to detect metadata corruption that confuses planning
- Upgrade Thanos — several planner bugs (e.g. with vertical compaction) were fixed in later releases
Example fix
// before cg := compact.NewGroup(... /* custom planner with buggy extension */) // after cg := compact.NewGroup(logger, reg, bkt, keys, dir, compact.DefaultPlanner(syncer, enableVerticalCompaction), ...) // or fixed extension
Defensive patterns
Strategy: retry
Validate before calling
// Validate planner extensions in tests before production:
plan, err := planner.Plan(ctx, metas, errChan, ext); if err != nil { t.Fatal(err) } Try / catch
if err := cg.Compact(ctx); err != nil {
if errors.Is(err, context.Canceled) { return } // expected shutdown
log.Error(err, "compaction planning failed; will retry next loop")
} Prevention
- Test custom compaction planners/extensions against real bucket metadata
- Run bucket verify regularly to catch metadata issues early
- Keep Thanos version current — planner bugs are fixed over time
When it happens
Trigger: planner.Plan(ctx, cg.metasByMinTime, errChan, cg.Extensions()) returns a non-nil error, typically from a custom compaction extension or an internal planner invariant failure.
Common situations: Custom compaction extensions (planner from --compact.filter-conflict... or code using compact.NewGroup with a custom Planner) returning errors; metadata inconsistencies the DefaultPlanner cannot resolve; bugs in extension implementations.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- create bucket compactor
- compaction
- critical error detected
- error executing compaction
- could not group metadata for compaction
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/48011275b015328d.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/compact/compact.go:1188
// Check for overlapped blocks.
overlappingBlocks := false
if err := cg.areBlocksOverlapping(nil); err != nil {
// TODO(bwplotka): It would really nice if we could still check for other overlaps than replica. In fact this should be checked
// in syncer itself. Otherwise with vertical compaction enabled we will sacrifice this important check.
if !cg.enableVerticalCompaction {
return false, nil, halt(errors.Wrap(err, "pre compaction overlap check"))
}
overlappingBlocks = true
}
var toCompact []*metadata.Meta
if err := tracing.DoInSpanWithErr(ctx, "compaction_planning", func(ctx context.Context) (e error) {
toCompact, e = planner.Plan(ctx, cg.metasByMinTime, errChan, cg.Extensions())
return e
}); err != nil {
return false, nil, errors.Wrap(err, "plan compaction")
}
if len(toCompact) == 0 {
// Nothing to do.
return false, nil, nil
}
level.Info(cg.logger).Log("msg", "compaction available and planned", "plan", fmt.Sprintf("%v", toCompact))
// Once we have a plan we need to download the actual data.
groupCompactionBegin := time.Now()
begin := groupCompactionBegin
if err := compactionLifecycleCallback.PreCompactionCallback(ctx, cg.logger, cg, toCompact); err != nil {
return false, nil, errors.Wrapf(err, "failed to run pre compaction callback for plan: %s", fmt.Sprintf("%v", toCompact))
}
level.Info(cg.logger).Log("msg", "finished running pre compaction callback; downloading blocks", "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds(), "plan", fmt.Sprintf("%v", toCompact))
begin = time.Now()View on GitHub (pinned to 35b8b99117)