SigNoz/signoz · error
not a valid TTL duration %v
Error message
not a valid TTL duration %v
What it means
The 'duration' query parameter must be a valid Go duration string parseable by time.ParseDuration with a positive value (seconds > 0). Zero, negative, or malformed durations are rejected before the TTL is applied.
Source
Thrown at pkg/query-service/app/parser.go:443
// make sure either of the query params are present
typeTTL := r.URL.Query().Get("type")
delDuration := r.URL.Query().Get("duration")
coldStorage := r.URL.Query().Get("coldStorage")
toColdDuration := r.URL.Query().Get("toColdDuration")
if len(typeTTL) == 0 || len(delDuration) == 0 {
return nil, fmt.Errorf("type and duration param cannot be empty from the query")
}
// Validate the type parameter
if typeTTL != retentiontypes.TraceTTL && typeTTL != retentiontypes.MetricsTTL && typeTTL != retentiontypes.LogsTTL {
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()),View on GitHub (pinned to 5069bf80b0)
Solutions
- Use Go duration syntax with a unit, e.g. duration=72h or duration=48h0m0s
- Ensure the value is strictly positive
- If sending from code, format with time.Duration.String()
Example fix
// before ?type=traces&duration=72 // after ?type=traces&duration=72h
Defensive patterns
Strategy: validation
Validate before calling
d, err := time.ParseDuration(durationStr)
if err != nil || d <= 0 { return fmt.Errorf("duration must be a positive Go duration like 72h") } Prevention
- Always format durations with time.Duration.String()
- Never send bare integers as durations
When it happens
Trigger: Passing duration=0, duration=-24h, duration=72 (bare number, no unit), or duration=forever to setTTL.
Common situations: Passing a plain number of hours instead of a Go duration string; sending milliseconds as '72000' without a unit; frontend sending seconds as an integer.
Related errors
- SetTTLV2 only supported
- error while getting ttl. Err=%v
- type and duration param cannot be empty from the query
- type param should be metrics|traces|logs, got %v
- not a valid toCold TTL duration %v
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/1248d32975db0733.
Report an issue: GitHub.