thanos-io/thanos · error
cannot parse to a valid timestamp
Error message
cannot parse %q to a valid timestamp
What it means
The terminal error of parseTime: when the string is neither a parseable unix float nor a valid RFC3339Nano timestamp, this error is returned (and often wrapped by 'Invalid time value for %s' upstream). It is an ErrorBadData (HTTP 400) indicating the timestamp format is unrecognized.
Solutions
- Format the value as RFC3339Nano (e.g. 2024-01-02T15:04:05.999999999Z07:00).
- Or send a unix seconds float; convert ms epochs by dividing by 1000.
- URL-encode the timestamp so '+' and ':' survive transport.
- Add client-side pre-validation with the same two parse rules before calling the API.
Example fix
// before
params.set('start', '2024-01-02') // date-only, unparseable
// after
params.set('start', new Date('2024-01-02').toISOString()) // RFC3339 Defensive patterns
Strategy: validation
Validate before calling
const isValidApiTime = (s) => /^-?\d+(\.\d+)?$/.test(s) || !Number.isNaN(Date.parse(s)); // pre-check: if (!isValidApiTime(v)) fixBeforeRequest(v);
Type guard
function isParseableTimestamp(s) { return /^-?\d+(\.\d+)?$/.test(s) || !Number.isNaN(Date.parse(s)); } Prevention
- Use toISOString()/RFC3339Nano for all timestamp params.
- Never send date-only strings; include time and zone.
- Keep one shared timestamp serializer for all Thanos API calls.
When it happens
Trigger: Any time parameter receiving a string that fails strconv.ParseFloat and time.Parse(RFC3339Nano), e.g. 'time=2024-01-02' (date only, no time/zone) or 'time=1704153600000' passed as float is fine, but 'time=xyz' fails both paths.
Common situations: Date-only strings without T/Z suffix, epoch milliseconds as an integer string (parses as float seconds — yields a far-future time rather than this error, a subtle bug), locale-formatted datetimes, or empty-ish garbage values that slipped past empty checks.
Related errors
- Invalid time value for
- ID cannot be empty
- Action cannot be empty
- invalid targets parameter state=
- invalid rules parameter type=
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/9e2ff5364cfb9bed.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/query/v1.go:1599
return defaultValue, nil
}
result, err := parseTime(val)
if err != nil {
return time.Time{}, errors.Wrapf(err, "Invalid time value for '%s'", paramName)
}
return result, nil
}
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) {View on GitHub (pinned to 35b8b99117)