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

  1. Inspect the wrapped inner error to identify which planner/extension failed
  2. Disable custom compaction extensions and re-run with the DefaultPlanner
  3. Run 'thanos tools bucket verify' to detect metadata corruption that confuses planning
  4. 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

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


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)