SigNoz/signoz · error · model.ApiError
zero or negative query resolution step widths are not accept
Error message
zero or negative query resolution step widths are not accepted. Try a positive integer
What it means
The range query parser requires a strictly positive step (query resolution). A step of zero or negative would cause infinite points or division issues, so SigNoz (like Prometheus) rejects it with ErrorBadData.
Source
Thrown at pkg/query-service/app/parser.go:158
if err != nil {
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
end, err := parseMetricsTime(r.FormValue("end"))
if err != nil {
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
if end.Before(start) {
err := errors.New("end timestamp must not be before start time")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
step, err := parseMetricsDuration(r.FormValue("step"))
if err != nil {
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
if step <= 0 {
err := errors.New("zero or negative query resolution step widths are not accepted. Try a positive integer")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
// For safety, limit the number of returned points per timeseries.
// This is sufficient for 60s resolution for a week or 1h resolution for a year.
if end.Sub(start)/step > 11000 {
err := errors.New("exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
queryRangeParams := model.QueryRangeParams{
Start: start,
End: end,
Step: step,
Query: r.FormValue("query"),
Stats: r.FormValue("stats"),
}
View on GitHub (pinned to 5069bf80b0)
Solutions
- Set an explicit positive step such as step=15s or step=60
- Fix client-side step math: guard against division by zero and round up to at least 1 second
- Regenerate the URL after fixing the step parameter and retry
Example fix
// before
step := int(end.Sub(start).Seconds()) / numPoints // numPoints==0 -> 0
// after
if numPoints <= 0 {
numPoints = 100
}
step := int(end.Sub(start).Seconds()) / numPoints
if step < 1 {
step = 1
} Defensive patterns
Strategy: validation
Validate before calling
stepDur, err := time.ParseDuration(stepStr)
if err != nil || stepDur <= 0 {
stepDur = 60 * time.Second
}
resp, err := api.QueryRangeMetrics(ctx, start, end, stepDur, query) Prevention
- Default step to a sane positive value when user input is empty/zero
- Compute step from window size rather than hardcoding
- Reject step=0 early in UI controls
When it happens
Trigger: GET query_range with step=0, step=-15s, or a step string that parses to a zero duration (e.g. step=0s), or omitting calculations that default step to 0 in generated URLs.
Common situations: Dashboards computing step as (end-start)/N where N=0 or integer division truncates to 0; hardcoded step variables; migrating queries from systems where step=0 meant auto.
Related errors
- end timestamp must not be before start time
- exceeded maximum resolution of 11,000 points per timeseries.
- step param is not in correct format
- public_dashboard_invalid_input
- atleast 1 metric name must be specified
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/3b8695225bd11fef.
Report an issue: GitHub.