thanos-io/thanos · error

5m resolution retention must be higher than the minimum…

Error message

5m resolution retention must be higher than the minimum block size after which 1h resolution downsampling will occur (10 days)

What it means

A configuration validation error in runCompact (cmd/thanos/compact.go:423). When downsampling is enabled and a 5m retention is set, it must be at least downsample.ResLevel2DownsampleRange (10 days); otherwise 1h downsampling could never persist for those blocks, so startup is aborted.

Solutions

  1. Increase --retention.5m to at least 10 days (e.g. --retention.5m=240h)
  2. Pass --downsampling.disable if short 5m retention is intentional
  3. Set --retention.5m=0s to disable 5m retention, bypassing the check

Example fix

// before
thanos compact --retention.5m=96h ...
// after
thanos compact --retention.5m=240h ...
// or
thanos compact --downsampling.disable --retention.5m=96h ...
Defensive patterns

Strategy: validation

Validate before calling

ret5m := time.Duration(conf.retentionFiveMin)
if ret5m != 0 && !conf.disableDownsampling && ret5m < 10*24*time.Hour {
	return errors.New("--retention.5m must be >= 10d when downsampling is enabled")
}

Prevention

When it happens

Trigger: --downsampling.enabled plus --retention.5m set to a nonzero duration less than 10 days (e.g. 96h).

Common situations: Tuning 5m retention to a few days while downsampling is enabled; copying retention configs between clusters with different downsampling settings.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/fc19ce1e110f9089. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/compact.go:423

	}

	retentionByResolution := map[compact.ResolutionLevel]time.Duration{
		compact.ResolutionLevelRaw: time.Duration(conf.retentionRaw),
		compact.ResolutionLevel5m:  time.Duration(conf.retentionFiveMin),
		compact.ResolutionLevel1h:  time.Duration(conf.retentionOneHr),
	}

	if retentionByResolution[compact.ResolutionLevelRaw].Milliseconds() != 0 {
		// If downsampling is enabled, error if raw retention is not sufficient for downsampling to occur (upper bound 10 days for 1h resolution)
		if !conf.disableDownsampling && retentionByResolution[compact.ResolutionLevelRaw].Milliseconds() < downsample.ResLevel1DownsampleRange {
			return errors.New("raw resolution must be higher than the minimum block size after which 5m resolution downsampling will occur (40 hours)")
		}
		level.Info(logger).Log("msg", "retention policy of raw samples is enabled", "duration", retentionByResolution[compact.ResolutionLevelRaw])
	}
	if retentionByResolution[compact.ResolutionLevel5m].Milliseconds() != 0 {
		// If retention is lower than minimum downsample range, then no downsampling at this resolution will be persisted
		if !conf.disableDownsampling && retentionByResolution[compact.ResolutionLevel5m].Milliseconds() < downsample.ResLevel2DownsampleRange {
			return errors.New("5m resolution retention must be higher than the minimum block size after which 1h resolution downsampling will occur (10 days)")
		}
		level.Info(logger).Log("msg", "retention policy of 5 min aggregated samples is enabled", "duration", retentionByResolution[compact.ResolutionLevel5m])
	}
	if retentionByResolution[compact.ResolutionLevel1h].Milliseconds() != 0 {
		level.Info(logger).Log("msg", "retention policy of 1 hour aggregated samples is enabled", "duration", retentionByResolution[compact.ResolutionLevel1h])
	}

	var cleanMtx sync.Mutex
	// TODO(GiedriusS): we could also apply retention policies here but the logic would be a bit more complex.
	cleanPartialMarked := func() error {
		cleanMtx.Lock()
		defer cleanMtx.Unlock()

		compact.BestEffortCleanAbortedPartialUploads(ctx, logger, sy.Partial(), insBkt, compactMetrics.partialUploadDeleteAttempts, compactMetrics.blocksCleaned, compactMetrics.blockCleanupFailures, ignoreDeletionMarkFilter.DeletionMarkBlocks())
		compactMetrics.cleanups.Inc()

		return nil
	}

View on GitHub (pinned to 35b8b99117)