Skip to content

fix(pushgateway): base64-encode empty and slash-containing path values - #871

Open
sarankumar1325 wants to merge 2 commits into
prometheus:mainfrom
sarankumar1325:fix/pushgateway-base64-grouping
Open

sarankumar1325 wants to merge 2 commits into
prometheus:mainfrom
sarankumar1325:fix/pushgateway-base64-grouping

Conversation

@sarankumar1325

@sarankumar1325 sarankumar1325 commented Oct 31, 2026 •

Copy link
Copy Markdown

The Pushgateway can't take every job name or grouping value as a plain path segment. Its README says:

  • An empty label value gives // or a trailing /, which its router strips, so /metrics/job/example/first_label//second_label/foobar doesn't work.
  • A / in a job name or label value is read as a path separator, even when URI-encoded as %2F.

For both cases the Pushgateway wants the name suffixed with @base64 and the value sent as URL-safe base64, with = for an empty value (/metrics/job/example/first_label@base64/=/...). The README adds "Ideally, client libraries take care of the suffixing and encoding", and client_golang and client_python both do. Here, generateGroupings() and the job segment always used encodeURIComponent, so groupings: { first_label: '' } or { path: '/var/tmp' } produced a path the Pushgateway can't parse.

This change adds a small encodePathSegment() helper that both the job segment and the groupings use:

  • empty value → /<name>@base64/=
  • value containing / → /<name>@base64/<base64url>
  • . or .. → /<name>@base64/<base64url> (as plain segments these are dot segments, and the Pushgateway answers with a 307 redirect to the cleaned path, which is a different group; client_golang encodes them too)
  • anything else → /<name>/<encodeURIComponent(value)>, as before

So existing paths for normal values don't change.

Tests:

  • Two new pushAdd cases in test/pushgatewayTest.js: an empty grouping value (first@base64/=), and a job name plus grouping value that contain / (job@base64/YS9i/path@base64/L3Zhci90bXA). A third case covers a .. job name and a . grouping value (job@base64/Li4/first@base64/Lg). Across the registry/content-type variants they fail on main and pass with this change.
  • npm run lint, prettier --check, tsc --project . and the full jest suite (663 tests) pass.
  • CHANGELOG entry under Unreleased.

I found this while reading the code, with help from an AI assistant. I checked the change and the tests myself.

The Pushgateway cannot parse an empty grouping value (the path segment is
dropped by its router) or a job name/grouping value containing `/`, even
URI-encoded. For those it requires the label name to be suffixed with
`@base64` and the value to be URL-safe base64, with `=` for the empty
string. Encode those cases that way, like client_golang and
client_python do.

Signed-off-by: sarankumar1325 <120080287+sarankumar1325@users.noreply.github.com>
As plain path segments they are dot segments, and the Pushgateway
redirects the request to the cleaned path, a different group.

Signed-off-by: sarankumar1325 <120080287+sarankumar1325@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

1 participant