{"record":{"id":"c1bb4dfe628ddde8","repo":"SigNoz/signoz","slug":"end-timestamp-must-not-be-before-start-time","errorCode":null,"errorMessage":"end timestamp must not be before start time","messagePattern":"end timestamp must not be before start time","errorType":"validation","errorClass":"model.ApiError","httpStatus":400,"severity":"error","filePath":"pkg/query-service/app/parser.go","lineNumber":148,"sourceCode":"\t\tTime:  ts,\n\t\tQuery: r.FormValue(\"query\"),\n\t\tStats: r.FormValue(\"stats\"),\n\t}, nil\n\n}\n\nfunc parseQueryRangeRequest(r *http.Request) (*model.QueryRangeParams, *model.ApiError) {\n\n\tstart, err := parseMetricsTime(r.FormValue(\"start\"))\n\tif err != nil {\n\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}\n\t}\n\tend, err := parseMetricsTime(r.FormValue(\"end\"))\n\tif err != nil {\n\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}\n\t}\n\tif end.Before(start) {\n\t\terr := errors.New(\"end timestamp must not be before start time\")\n\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}\n\t}\n\n\tstep, err := parseMetricsDuration(r.FormValue(\"step\"))\n\tif err != nil {\n\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}\n\t}\n\n\tif step <= 0 {\n\t\terr := errors.New(\"zero or negative query resolution step widths are not accepted. Try a positive integer\")\n\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}\n\t}\n\n\t// For safety, limit the number of returned points per timeseries.\n\t// This is sufficient for 60s resolution for a week or 1h resolution for a year.\n\tif end.Sub(start)/step > 11000 {\n\t\terr := errors.New(\"exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)\")\n\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/app/parser.go#L130-L166","documentation":"The metrics range query parser rejects a time range where end is chronologically before start. SigNoz enforces this because a backwards range cannot produce a meaningful time series and would break downstream PromQL-style evaluation.","triggerScenarios":"GET /api/v1/query_range (or the SigNoz metrics range API) where the end timestamp parses to an earlier instant than start, e.g. start=2026-08-28T10:00:00&end=2026-08-28T09:00:00, often from swapped variables or unit confusion (seconds vs milliseconds).","commonSituations":"Swapping start/end in dashboards or curl commands; passing timestamps in different units or timezones so comparison inverts; relative-time templates (now-1h vs now) wired backwards.","solutions":["Swap the start and end parameters so start is the earlier instant","Validate that both timestamps use the same unit (Unix seconds) and timezone before sending","If computing ranges in code, assert end.After(start) or end.Equal(start) before the request"],"exampleFix":"// before\nparams := url.Values{}\nparams.Set(\"start\", endTs)\nparams.Set(\"end\", startTs)\n// after\nparams := url.Values{}\nparams.Set(\"start\", startTs)\nparams.Set(\"end\", endTs)","handlingStrategy":"validation","validationCode":"if end.Before(start) {\n    end, start = start, end // or return an error to the user\n}\nresp, err := api.QueryRangeMetrics(ctx, start, end, step, query)","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if apiErr, ok := err.(*model.ApiError); ok && apiErr.Typ == model.ErrorBadData && strings.Contains(err.Error(), \"must not be before\") {\n        log.Printf(\"inverted time range from user %s..%s\", start, end)\n    }\n}","preventionTips":["Normalize all timestamps to Unix seconds UTC before building requests","Validate start <= end in dashboard variable code","Add unit tests for boundary ranges (equal start/end, swapped)"],"tags":["validation","metrics","time-range","promql"],"backgroundTag":"invalid-time-range","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}