thanos-io/thanos · error

cannot parse to a valid duration. It overflows int64

Error message

cannot parse %q to a valid duration. It overflows int64

What it means

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.

Solutions

  1. Send a smaller numeric duration (seconds) that fits in an int64 nanosecond value (max ~292 years).
  2. Use a Prometheus model duration string like `1h`, `5m`, `30s` instead of a raw float.
  3. Clamp or validate the duration client-side before issuing the request.

Example fix

// before
GET /api/v1/query?query=up&timeout=1e20
// after
GET /api/v1/query?query=up&timeout=30s
Defensive patterns

Strategy: validation

Validate before calling

function validDuration(s) {
  const d = Number(s);
  if (!Number.isNaN(d) && Number.isFinite(d)) return d * 1e9 <= Number.MAX_SAFE_INTEGER && d * 1e9 >= -Number.MAX_SAFE_INTEGER;
  return /^\d+(ms|s|m|h|d|w|y)$/.test(s);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/ad103bc433ea3d0b. Report an issue: GitHub.

Appendix: source

Thrown at pkg/api/query/v1.go:1606

}

func parseTime(s string) (time.Time, error) {
	if t, err := strconv.ParseFloat(s, 64); err == nil {
		s, ns := math.Modf(t)
		ns = math.Round(ns*1000) / 1000
		return time.Unix(int64(s), int64(ns*float64(time.Second))), nil
	}
	if t, err := time.Parse(time.RFC3339Nano, s); err == nil {
		return t, nil
	}
	return time.Time{}, errors.Errorf("cannot parse %q to a valid timestamp", s)
}

func parseDuration(s string) (time.Duration, error) {
	if d, err := strconv.ParseFloat(s, 64); err == nil {
		ts := d * float64(time.Second)
		if ts > float64(math.MaxInt64) || ts < float64(math.MinInt64) {
			return 0, errors.Errorf("cannot parse %q to a valid duration. It overflows int64", s)
		}
		return time.Duration(ts), nil
	}
	if d, err := model.ParseDuration(s); err == nil {
		return time.Duration(d), nil
	}
	return 0, errors.Errorf("cannot parse %q to a valid duration", s)
}

// parseLimitParam returning 0 means no limit is to be applied.
func parseLimitParam(s string) (int, error) {
	if s == "" {
		return 0, nil
	}

	limit, err := strconv.Atoi(s)
	if err != nil {
		return 0, errors.Errorf("cannot parse %q to a valid limit", s)

View on GitHub (pinned to 35b8b99117)