{"record":{"id":"ad103bc433ea3d0b","repo":"thanos-io/thanos","slug":"cannot-parse-q-to-a-valid-duration-it-overflows","errorCode":null,"errorMessage":"cannot parse %q to a valid duration. It overflows int64","messagePattern":"cannot parse %q to a valid duration\\. It overflows int64","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/api/query/v1.go","lineNumber":1606,"sourceCode":"}\n\nfunc parseTime(s string) (time.Time, error) {\n\tif t, err := strconv.ParseFloat(s, 64); err == nil {\n\t\ts, ns := math.Modf(t)\n\t\tns = math.Round(ns*1000) / 1000\n\t\treturn time.Unix(int64(s), int64(ns*float64(time.Second))), nil\n\t}\n\tif t, err := time.Parse(time.RFC3339Nano, s); err == nil {\n\t\treturn t, nil\n\t}\n\treturn time.Time{}, errors.Errorf(\"cannot parse %q to a valid timestamp\", s)\n}\n\nfunc parseDuration(s string) (time.Duration, error) {\n\tif d, err := strconv.ParseFloat(s, 64); err == nil {\n\t\tts := d * float64(time.Second)\n\t\tif ts > float64(math.MaxInt64) || ts < float64(math.MinInt64) {\n\t\t\treturn 0, errors.Errorf(\"cannot parse %q to a valid duration. It overflows int64\", s)\n\t\t}\n\t\treturn time.Duration(ts), nil\n\t}\n\tif d, err := model.ParseDuration(s); err == nil {\n\t\treturn time.Duration(d), nil\n\t}\n\treturn 0, errors.Errorf(\"cannot parse %q to a valid duration\", s)\n}\n\n// parseLimitParam returning 0 means no limit is to be applied.\nfunc parseLimitParam(s string) (int, error) {\n\tif s == \"\" {\n\t\treturn 0, nil\n\t}\n\n\tlimit, err := strconv.Atoi(s)\n\tif err != nil {\n\t\treturn 0, errors.Errorf(\"cannot parse %q to a valid limit\", s)","sourceCodeStart":1588,"sourceCodeEnd":1624,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/api/query/v1.go#L1588-L1624","documentation":"parseDuration accepts either a float (seconds) or a Prometheus model duration string. If the float parse succeeds but the resulting nanosecond value exceeds int64 range (math.MaxInt64/MinInt64), the conversion is impossible and this error is thrown to signal overflow.","triggerScenarios":"Passing a numeric duration like `?timeout=1e20` or `&timeout=99999999999999999999` to a Thanos Query API endpoint (e.g. /api/v1/query timeout param) that routes through parseDuration.","commonSituations":"Clients or dashboards computing timeouts in nanoseconds/milliseconds as huge floats; misconfigured alerting tools sending unbounded durations; unit confusion (s vs ns) when building query URLs programmatically.","solutions":["Send a smaller numeric duration (seconds) that fits in an int64 nanosecond value (max ~292 years).","Use a Prometheus model duration string like `1h`, `5m`, `30s` instead of a raw float.","Clamp or validate the duration client-side before issuing the request."],"exampleFix":"// before\nGET /api/v1/query?query=up&timeout=1e20\n// after\nGET /api/v1/query?query=up&timeout=30s","handlingStrategy":"validation","validationCode":"function validDuration(s) {\n  const d = Number(s);\n  if (!Number.isNaN(d) && Number.isFinite(d)) return d * 1e9 <= Number.MAX_SAFE_INTEGER && d * 1e9 >= -Number.MAX_SAFE_INTEGER;\n  return /^\\d+(ms|s|m|h|d|w|y)$/.test(s);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always send Prometheus duration strings like 30s, 5m, 1h.","Clamp numeric durations to < 9.2e18 nanoseconds (~292 years).","Centralize duration formatting in one client helper."],"tags":["duration","overflow","query-api","bad-request"],"backgroundTag":"invalid-duration-format","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}