SigNoz/signoz · error

delete TTL should be greater than cold storage move TTL

Error message

delete TTL should be greater than cold storage move TTL

What it means

Data must live on hot storage longer than the cold-storage move threshold, so toColdDuration must be strictly less than the overall delete TTL duration. If toColdParsed >= durationParsed the request is rejected.

Source

Thrown at pkg/query-service/app/parser.go:455

		return nil, fmt.Errorf("type param should be metrics|traces|logs, got %v", typeTTL)
	}

	// Validate the TTL duration.
	durationParsed, err := time.ParseDuration(delDuration)
	if err != nil || durationParsed.Seconds() <= 0 {
		return nil, fmt.Errorf("not a valid TTL duration %v", delDuration)
	}

	var toColdParsed time.Duration

	// If some cold storage is provided, validate the cold storage move TTL.
	if len(coldStorage) > 0 {
		toColdParsed, err = time.ParseDuration(toColdDuration)
		if err != nil || toColdParsed.Seconds() <= 0 {
			return nil, fmt.Errorf("not a valid toCold TTL duration %v", toColdDuration)
		}
		if toColdParsed.Seconds() != 0 && toColdParsed.Seconds() >= durationParsed.Seconds() {
			return nil, fmt.Errorf("delete TTL should be greater than cold storage move TTL")
		}
	}

	return &retentiontypes.TTLParams{
		Type:                  typeTTL,
		DelDuration:           int64(durationParsed.Seconds()),
		ColdStorageVolume:     coldStorage,
		ToColdStorageDuration: int64(toColdParsed.Seconds()),
	}, nil
}

func parseGetTTL(r *http.Request) (*retentiontypes.GetTTLParams, error) {

	typeTTL := r.URL.Query().Get("type")

	if len(typeTTL) == 0 {
		return nil, fmt.Errorf("type param cannot be empty from the query")
	} else {

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Make duration strictly greater than toColdDuration (e.g. duration=72h, toColdDuration=24h)
  2. If you intended no cold tier, remove the coldStorage and toColdDuration params entirely
  3. Re-read the semantics: duration = total retention before delete; toColdDuration = age at which data moves to cold

Example fix

// before
?type=traces&duration=24h&coldStorage=s3&toColdDuration=48h
// after
?type=traces&duration=72h&coldStorage=s3&toColdDuration=24h
Defensive patterns

Strategy: validation

Validate before calling

del, _ := time.ParseDuration(duration)
move, _ := time.ParseDuration(toColdDuration)
if move >= del { return fmt.Errorf("toColdDuration must be < duration") }

Prevention

When it happens

Trigger: ?duration=24h&toColdDuration=24h, or ?duration=24h&toColdDuration=48h — any case where the move-to-cold age meets or exceeds the deletion age.

Common situations: Misreading which param is which and swapping them; incrementing retention duration without adjusting toColdDuration; equal-value configs.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/8ce9563cf891447d. Report an issue: GitHub.