Skip to content

Support partial write on PRW2.0 - #7761

Open
SungJin1212 wants to merge 1 commit into
masterfrom
PRW2-support-partial-write
Open

Support partial write on PRW2.0#7761
SungJin1212 wants to merge 1 commit into
masterfrom
PRW2-support-partial-write

Conversation

@SungJin1212

@SungJin1212 SungJin1212 commented Aug 13, 2026

Copy link
Copy Markdown
Member

Implements partial write for Prometheus Remote Write 2.0 requests, following the Prometheus receiver behavior.
Previously a single invalid series aborted the whole conversion, so the entire batch was rejected with a 400 and the X-Prometheus-Remote-Write-*-Written response headers were not set at all; now invalid series are skipped and reported together in the response, the valid ones are written, and the written stats headers are always set.

This also makes Cortex accept a v2 write request that contains an exemplar-only series.

Which issue(s) this PR fixes:
Fixes #

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]
  • docs/configuration/v1-guarantees.md updated if this PR introduces experimental flags

@dosubot dosubot Bot added go Pull requests that update Go code type/feature labels Aug 13, 2026
@SungJin1212 SungJin1212 changed the title Support partial write Support partial write on PRW2.0 Aug 13, 2026
@SungJin1212
SungJin1212 force-pushed the PRW2-support-partial-write branch from af8e168 to b3a5222 Compare August 14, 2026 01:49
@yeya24

yeya24 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Previously a single invalid series aborted the whole conversion, so the entire batch was rejected with a 400 and the X-Prometheus-Remote-Write-*-Written response headers were not set at all; now invalid series are skipped and reported together in the response, the valid ones are written, and the written stats headers are always set.

Interesting, is this what Prometheus does today? If that's Prometheus' behavior I am ok with it. But it is a behavior change in Cortex regardless. Do you think we can put this behind a FF?

@SungJin1212

Copy link
Copy Markdown
Member Author

Interesting, is this what Prometheus does today?

Yes, Prometheus' v2 receiver has addressed the partial write since v2.54.0.

Do you think we can put this behind a FF?

I'd rather not add another flag here: the v2 path is already opt-in and experimental. Currently, Prometheus can send exemplar-only series (prometheus/prometheus#17857), and Cortex drops the whole request, so partial write is what makes exemplars usable over RW2.0 at all.
Or how about a flag that defaults to true?

@SungJin1212
SungJin1212 requested a review from yeya24 August 18, 2026 01:39
@SungJin1212
SungJin1212 force-pushed the PRW2-support-partial-write branch from b3a5222 to 68dd0a9 Compare August 20, 2026 05:26
@SungJin1212
SungJin1212 force-pushed the PRW2-support-partial-write branch from 7e843c3 to 495f7c5 Compare August 20, 2026 07:10
@SungJin1212
SungJin1212 requested review from a team and friedrichg August 23, 2026 09:46

@friedrichg friedrichg 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.

Thanks for this. The partial write looks right to me and matches the spec, which requires a non-2xx on partial writes and requires the X-Prometheus-Remote-Write-*-Written headers on failures too, so not setting them on a 400 was a spec violation before.

Could we split the exemplar-only acceptance into a follow-up PR? It is independent of partial write, and it carries an open question that partial write does not:

  • It is deliberately more permissive than the Prometheus receiver, which still rejects exemplar-only TimeSeries.
  • The upstream direction is unresolved. prometheus/prometheus#17857 is open with two competing approaches.
  • It only works when the series already exists in the ingester. app.AppendExemplar does not create the series, so for a new series the ingester soft fails with errExemplarRef, returns 400, and drops the exemplar. Making it work properly needs an ingester change, which is its own discussion about series creation and limits.

Comment thread pkg/util/push/push.go
Comment on lines +294 to +295
// An out of range UnitRef only invalidates the metadata, so keep the series and
// let convertV2ToV1Metadata report it.

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.

What happens if UnitRef is out of range and enableTypeAndUnitLabels is on? unit is "" here, so shouldAttachTypeAndUnitLabels below decides from the type alone and we store the series without the unit label the sender sent, under a different identity.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Should we drop the series when UnitRef is out of range and enableTypeAndUnitLabels is on?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It only works when the series already exists in the ingester. app.AppendExemplar does not create the series, so for a new series the ingester soft fails with errExemplarRef, returns 400, and drops the exemplar. Making it work properly needs an ingester change, which is its own discussion about series creation and limits.

I never thought about it. I changed to drop the exemplar-only series and updated it to the latest commit.

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.

Yes, exactly this. With the flag on, unit feeds unit, which is part of the series identity, so keeping the series stores it under a label set the sender never sent. Dropping it and reporting the error is what current Prometheus does for any bad metadata ref.

Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
@SungJin1212
SungJin1212 force-pushed the PRW2-support-partial-write branch from 5239c85 to 98b7ce7 Compare August 25, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Pull requests that update Go code size/XL type/feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants