Skip to content

api/prometheus: clamp out-of-range formatted timestamps#2040

Open
happysnaker wants to merge 1 commit into
prometheus:mainfrom
happysnaker:fix-951-earliest-time-format
Open

api/prometheus: clamp out-of-range formatted timestamps#2040
happysnaker wants to merge 1 commit into
prometheus:mainfrom
happysnaker:fix-951-earliest-time-format

Conversation

@happysnaker

Copy link
Copy Markdown

Summary

Clamp extremely low/high time.Time values to Prometheus's documented parseable API boundary timestamps before formatting query parameters.

What this fixes

Issue #951 reports that passing model.Earliest.Time() through the client ends up formatting to a rounded float value like -9223372036854776, which overflows back into a large positive timestamp on the server side.

This patch keeps normal timestamp formatting in the existing numeric API style, but special-cases values at or beyond the Prometheus API boundary sentinels so they serialize to the same RFC3339 strings that the server already recognizes explicitly.

Details

  • keep regular timestamps in the current numeric form
  • avoid relying on time.Time.UnixNano() for out-of-range values
  • clamp values at/beyond the effective API boundaries to the server-compatible minTimeFormatted / maxTimeFormatted strings
  • add focused regression tests for:
    • normal timestamps
    • negative fractional timestamps
    • model.Earliest.Time()
    • model.Latest.Time()

Fixes #951

@happysnaker

Copy link
Copy Markdown
Author

Maintainer context for review:

  • issue API passes model.Earliest incorrectly #951 points out that float-based formatting can round model.Earliest / model.Latest into values that overflow back on the server side
  • this patch keeps the existing numeric timestamp style for normal values
  • it only clamps values at or beyond the effective Prometheus API boundaries to the same parseable boundary strings the server already special-cases

So the behavior change is intentionally narrow: fix the extreme out-of-range edge case without changing normal query parameter formatting.

Signed-off-by: Shirong Lu <73147033+happysnaker@users.noreply.github.com>
@happysnaker
happysnaker force-pushed the fix-951-earliest-time-format branch from 6081f02 to 38d309a Compare July 1, 2026 16:01

@bwplotka bwplotka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting one! It's not great if HTTP client changes the time ranges you ask for underhood.

But for general practicality that would make sense. People use lowest and highest for "any" range purpose. Let's fix this this way 👍🏽

One nit only, thanks!

Comment thread api/prometheus/v1/api.go
Comment on lines +1579 to +1583
// Prometheus's HTTP API accepts these boundary timestamps explicitly even
// though Go's RFC3339 parser cannot round-trip years with more than four
// digits. Keep these values aligned with the server-side defaults so very
// low/high sentinels like model.Earliest and model.Latest map to something
// the API can parse without overflowing.

@bwplotka bwplotka Jul 10, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's mention the relevant server side code

Suggested change
// Prometheus's HTTP API accepts these boundary timestamps explicitly even
// though Go's RFC3339 parser cannot round-trip years with more than four
// digits. Keep these values aligned with the server-side defaults so very
// low/high sentinels like model.Earliest and model.Latest map to something
// the API can parse without overflowing.
// Prometheus's HTTP API accepts these boundary timestamps explicitly even
// though Go's RFC3339 parser cannot round-trip years with more than four
// digits. Keep these values aligned with the server-side defaults so very
// low/high sentinels like model.Earliest and model.Latest map to something
// the API can parse without overflowing.
// Reference: https://github.com/prometheus/prometheus/blob/10cbff99a9d5998c4a5ad998b6cf41ea269bde08/web/api/v1/api.go#L834

@kakkoyun

Copy link
Copy Markdown
Member

@happysnaker Would you have a look? We will cut a release soon and this could be included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API passes model.Earliest incorrectly

3 participants