From 856521ec3aa15068a8654acd17b9dbbe88e80789 Mon Sep 17 00:00:00 2001 From: Jan Fajerski Date: Mon, 14 Sep 2026 16:55:13 +0200 Subject: [PATCH 1/6] prepare v3.15.0-rc.0 (#19669) prepare v3.15.0-rc.0 Signed-off-by: Jan Fajerski --- CHANGELOG.md | 80 +++++++++++++++++++- VERSION | 2 +- web/ui/mantine-ui/package.json | 2 +- web/ui/module/codemirror-promql/package.json | 2 +- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package.json | 4 +- web/ui/react-app/package.json | 2 +- 7 files changed, 86 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eef6eba60..f2465017ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,85 @@ ## main / unreleased -- [ENHANCEMENT] Remote write / Alertmanager: Upgrade `github.com/prometheus/sigv4` to v0.5.0, adding `session_name` and `tags` fields to the `sigv4` configuration block for STS AssumeRole sessions. The existing but previously undocumented `service_name` field is also documented. +## 3.15.0-rc.0 / 2026-09-09 +- [CHANGE] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. Add tests to prevent regression of the fix made in #18081. #18598 +- [CHANGE] PromQL: Do not register a start timestamp reset if the start timestamp hasn't changed between subsequent samples. #19454 +- [CHANGE] Logging: Deprecate `--log.level`; use `runtime.log_level` configuration to supply the default level. #19511 +- [FEATURE] Configuration: Allow changing the process log level through `runtime.log_level` on configuration reload. #19511 +- [FEATURE] Prometheus: Add `--auto-gomemlimit.refresh-interval` flag to periodically re-detect the container or system memory limit and update `GOMEMLIMIT` at runtime. #18843 +- [FEATURE] Scraping: Add support for scraping targets via Unix Domain Sockets. #12024. #18091 +- [FEATURE] scrape: Implement OM2.0 scrape format. #18606 +- [ENHANCEMENT] Reduce TSDB head CPU utilization when initializing. #18001 +- [ENHANCEMENT] Docker SD: Add labels `__meta_docker_container_image` and `__meta_docker_container_image_id`. #19386 +- [ENHANCEMENT] Mixin: Add a p95/p99 remote-write send-batch latency panel to the remote-write dashboard. #19500 +- [ENHANCEMENT] Mixin: Support native histograms in the remote-write send-batch latency panel. #19522 +- [ENHANCEMENT] PromQL/TSDB: The `--enable-feature=st-storage` flag now automatically enables XOR2 float chunk encoding and ST-capable histogram chunk encoding, so you no longer need to pass `xor2-encoding` and `histograms-st-encoding` alongside it. #19518 +- [ENHANCEMENT] Remote write / Alertmanager: upgrade sigv4 to v0.5.0, adding `session_name` and `tags` fields for STS AssumeRole sessions. The previously undocumented `service_name` field is now also documented. #19569 +- [ENHANCEMENT] Scraping: Support zstd-compressed scrape responses, enabled via feature flag `zstd-scrape`. #19502 +- [ENHANCEMENT] TSDB: Stabilize the XOR2 float chunk encoding. `--enable-feature=xor2-encoding` is deprecated; use `storage.tsdb.chunk_encoding.floats: xor2` instead. Check that other software reading the TSDB directly (e.g. Thanos sidecar) supports XOR2 before enabling. #19461 +- [ENHANCEMENT] TSDB: add `prometheus_tsdb_head_appenders_created_total` metric. #19411 +- [ENHANCEMENT] Tracing: add more spans to scrapes, API queries and rule evaluations. #19410 +- [ENHANCEMENT] UI: Show the effective configuration for each scrape pool on the Targets and Service Discovery pages. #19384 +- [ENHANCEMENT] scrape: Enable start time synthesis for summary `_count` and `_sum` series in scrape appender v2. #19323 +- [ENHANCEMENT] scrape: stop all pools in parallel for faster shutdowns. #19295 +- [ENHANCEMENT] storage/remote: Add undocumented failed_request_logging config field to debug log remote write V2 requests on send errors. #19249 +- [ENHANCEMENT] TSDB: Add fast path for XOR chunk decompression to speed up queries. #18049 +- [ENHANCEMENT] UI: Improve native histogram table formatting and add a background bar indicating the bucket count. #19332 +- [ENHANCEMENT] TSDB: Add `prometheus_tsdb_head_series_pending_commit_underflow_total` to report pending-sample reservation underflows. #19470 +- [PERF] AWS SD: Build RDS cluster labels once per cluster instead of once per instance. #19504 +- [PERF] AWS SD: Describe RDS instances of different clusters concurrently, bounded by `request_concurrency`. #19506 +- [PERF] AWS SD: Describe each ElastiCache resource once per refresh instead of twice. #19585 +- [PERF] Remote read: Avoid cloning labels for sampled reads when no external labels are configured. #19503 +- [PERF] Remote write: Reuse OTLP converter scratch state between requests. #19388 +- [PERF] scrape: conversion from classic to native histograms should only parse start times when enabled. #19446 +- [BUGFIX] PromQL: Fix `info()` enrichment for composite expressions with mixed `@`/offset references or selector-free vector branches, preventing metadata from being evaluated at an unrelated timestamp. #19387 +- [BUGFIX] PromQL: Fix info() enrichment when input series use different subsets of identifying labels. #19557 +- [BUGFIX] PromQL: Preserve metric-name dropping through the info function when delayed name removal is enabled. #19413 +- [BUGFIX] TSDB: Don't silently drop samples when head garbage collection removes a series while it is being appended to. #19272 +- [BUGFIX] TSDB: Keep series with uncommitted samples during selected- and stale-series compaction, including when appenders overlap. #19470 +- [BUGFIX] TSDB: Do not retain head series after a synthetic start-timestamp zero sample is rejected. #19470 +- [BUGFIX] TSDB: Prevent query panics during series eviction after WAL replay. #19664 +- [BUGFIX] TSDB: fix potential deadlock between mmapSeriesChunks and gcSeries. #19460 +- [BUGFIX] TSDB: fix default block reload interval for custom options. #19368 +- [BUGFIX] AWS SD: Do not crash on serverless MSK clusters or MSK clusters without Open Monitoring. #19194 +- [BUGFIX] AWS SD: Do not panic when the ElastiCache API omits optional fields of a serverless cache or cache cluster. #19435 +- [BUGFIX] AWS SD: Reject non-positive `request_concurrency` instead of hanging service discovery indefinitely. #19524 +- [BUGFIX] Discovery/AWS: Avoid a panic when discovering standalone ECS tasks with custom task groups. #19302 +- [BUGFIX] Discovery: Do not panic in AWS Lightsail service discovery when an instance is missing optional fields such as availability zone, blueprint, bundle, name, state or support code. #19324 +- [BUGFIX] Discovery: delete the stale `prometheus_sd_last_update_timestamp_seconds` series for a config that is removed on reload. #19131 +- [BUGFIX] HTTP: Avoid truncating compressed responses when handlers set Content-Length. #19661 +- [BUGFIX] IONOS SD: Do not panic when the API response omits the server, NIC or volume collections, or a server's properties. #19438 +- [BUGFIX] Metadata will not affect the number of Remote Write v2 shards. #19218 +- [BUGFIX] Mixins: Fix label mismatches that prevented PrometheusHAGroupNotIngestingSamples and PrometheusHAGroupCrashlooping from firing. #19444 +- [BUGFIX] Native histograms: `DetectReset` no longer misses a counter reset when a populated bucket behind an empty one disappears, which could make histogram `rate()`/`increase()` undercount. #19367 +- [BUGFIX] Never skip histogram buckets for histogram_stddev and histogram_stdvar functions. #19521 +- [BUGFIX] OTLP: Do not abort an entire OTLP payload ingestion if one metric has no datapoints. #19343 +- [BUGFIX] PromQL: Fix FastRegexMatcher false-positive match when a capturing group is directly adjacent to a literal (e.g. `.*\|(foo)\|.*`). #19516 +- [BUGFIX] PromQL: Fix a panic in range selectors using the experimental `anchored` or `smoothed` modifier when the selected series has no samples inside the query window, for example a query evaluated inside a scrape gap. #19431 +- [BUGFIX] PromQL: Fix empty results when a subquery with `@` is used as the matrix argument of a call that is not step-invariant (for example `quantile_over_time(scalar(x), metric[...:...] @ T)`). #19187 +- [BUGFIX] PromQL: Make the "found duplicate series for the match group" many-to-many matching error message deterministic by sorting the two duplicate labels. #18810 +- [BUGFIX] PromQL: Preserve parentheses around duration literals on Expr.String() round-trip. #19403 +- [BUGFIX] PromQL: Reject duration-expression offsets and `@ start()` / `@ end()` before range selectors, matching the existing rejection of literal offsets and `@ `. #19406 +- [BUGFIX] PromQL: Report the position of the histogram argument rather than of a scalar argument in the native histogram NaN observation annotations of `histogram_quantile` and `histogram_fraction`. #19330 +- [BUGFIX] PromQL: info() now applies the @ modifier/offset when evaluating the info series, so info(v @ T) enriches as of T consistently instead of depending on the query start/eval time. #19266 +- [BUGFIX] Rules: Fix a panic when a rule manager created without a logger loads a rule file containing multiple YAML documents. #19433 +- [BUGFIX] Scrape: Do not append a stale marker for a series that is still exposed when the storage returns a new series reference for it. #19328 +- [BUGFIX] Scrape: JSON log formatter correctly format scrape target info. #19472 +- [BUGFIX] TSDB: Fix in-order chunk ID overflow by wrapping head chunk IDs modulo 2^23 so they never collide with the out-of-order flag bit. #19450 +- [BUGFIX] TSDB: Fix out-of-order chunk ID overflow by wrapping `firstOOOChunkID` modulo 2^23 instead of growing unbounded. #19216 +- [BUGFIX] UI: Remove an extraneous X-axis tick mark in the native histogram chart when using the "linear" display mode. #19326 +- [BUGFIX] discovery/aws: Avoid a panic when an ElastiCache ARN is missing its resource ID. #19333 +- [BUGFIX] discovery/aws: Do not panic on MSK clusters whose optional API fields are absent. #19584 +- [BUGFIX] discovery/aws: Do not panic when the EC2 API omits optional instance fields. #19512 +- [BUGFIX] discovery/aws: Don't panic on ECS tasks with absent optional fields. #19396 +- [BUGFIX] discovery/aws: MSK Optional Custom Configuration Fields #19422. #19422 +- [BUGFIX] discovery/ionos: Fix panic when the IONOS API omits optional server fields. #19418 +- [BUGFIX] discovery/kubernetes: Populate `__meta_kubernetes_service_loadbalancer_ip` from `status.loadBalancer.ingress`, falling back to deprecated `spec.loadBalancerIP`. #19404 +- [BUGFIX] histogram: Fix Compact moving buckets to wrong indices, and producing negative bucket counts for integer histograms, when more than one span is merged in the same pass. #19312 +- [BUGFIX] promtool: Fixed `tsdb dump` silently dropping native histogram samples. #18051 +- [BUGFIX] scrape: fix data race in `Manager.TargetsDroppedCounts` to avoid miscounting dropped targets. #19304 +- [BUGFIX] scrape: fix nil histogram when native and classic histograms are mixed in one metric family. #19452 +- [BUGFIX] TSDB: Fix WAL and GC log messages to emit human-readable duration strings instead of nanosecond integers. #19307 ## 3.14.0 / 2026-08-17 diff --git a/VERSION b/VERSION index f982feb41b..65af6bf36a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.14.0 +3.15.0-rc.0 diff --git a/web/ui/mantine-ui/package.json b/web/ui/mantine-ui/package.json index 3d6d6c4358..2e50ef5595 100644 --- a/web/ui/mantine-ui/package.json +++ b/web/ui/mantine-ui/package.json @@ -1,7 +1,7 @@ { "name": "@prometheus-io/mantine-ui", "private": true, - "version": "0.314.0", + "version": "0.315.0-rc.0", "type": "module", "scripts": { "start": "vite", diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index 098689d290..8b15fafa33 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.314.0", + "version": "0.315.0-rc.0", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index 4913620560..d5d09f0653 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.314.0", + "version": "0.315.0-rc.0", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package.json b/web/ui/package.json index a0d1ae8f05..b92e06f6be 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-io", "description": "Monorepo for the Prometheus UI", - "version": "0.314.0", + "version": "0.315.0-rc.0", "private": true, "scripts": { "build": "bash build_ui.sh --all", @@ -17,9 +17,9 @@ ], "devDependencies": { "@types/jest": "^30.0.0", - "@typescript/native": "npm:typescript@^7.0.0", "@typescript-eslint/eslint-plugin": "^8.65.0", "@typescript-eslint/parser": "^8.65.0", + "@typescript/native": "npm:typescript@^7.0.0", "eslint-config-prettier": "^10.1.8", "prettier": "^3.9.6", "ts-jest": "^29.4.12", diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index d9f2142d5b..48dd1edfaa 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.313.2", + "version": "0.315.0-rc.0", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.20.3", From a5268444426db30dcc677ba87b308492152a1136 Mon Sep 17 00:00:00 2001 From: Jan Fajerski Date: Tue, 22 Sep 2026 08:47:43 +0200 Subject: [PATCH 2/6] Prep release 3.15.0 rc.1 (#19790) * tsdb/agent: reset WAL buffers after write errors (#19700) * fix(tsdb/agent): reset WAL buffers after write errors Return encoded buffers to the shared pool with zero length even when WAL logging fails. This prevents later records from being appended to an earlier failed record. Fixes #19699 --------- Signed-off-by: fancivez * prepare v3.15.0-rc.1 Signed-off-by: Jan Fajerski --------- Signed-off-by: fancivez Signed-off-by: Jan Fajerski Co-authored-by: fancivez --- CHANGELOG.md | 3 + VERSION | 2 +- tsdb/agent/db.go | 4 +- tsdb/agent/db_test.go | 60 ++++++++++++++++++++ web/ui/mantine-ui/package.json | 2 +- web/ui/module/codemirror-promql/package.json | 2 +- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package.json | 2 +- web/ui/react-app/package.json | 2 +- 9 files changed, 71 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2465017ca..49fe72dc81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## main / unreleased +## 3.15.0-rc.1 / 2026-09-21 +- [BUGFIX] TSDB: Avoid WAL corruption after a failed WAL write in Agent mode. #19700 + ## 3.15.0-rc.0 / 2026-09-09 - [CHANGE] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. Add tests to prevent regression of the fix made in #18081. #18598 - [CHANGE] PromQL: Do not register a start timestamp reset if the start timestamp hasn't changed between subsequent samples. #19454 diff --git a/VERSION b/VERSION index 65af6bf36a..4a668e99c4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.15.0-rc.0 +3.15.0-rc.1 diff --git a/tsdb/agent/db.go b/tsdb/agent/db.go index 09e35f32a5..e7c694f786 100644 --- a/tsdb/agent/db.go +++ b/tsdb/agent/db.go @@ -1225,7 +1225,7 @@ func (a *appenderBase) log() error { encoder := record.Encoder{EnableSTStorage: a.opts.EnableSTStorage} buf := a.bufPool.Get().([]byte) defer func() { - a.bufPool.Put(buf) //nolint:staticcheck + a.bufPool.Put(buf[:0]) //nolint:staticcheck }() if len(a.pendingSeries) > 0 { @@ -1343,7 +1343,7 @@ func (a *appenderBase) logSeries() error { if len(a.pendingSeries) > 0 { buf := a.bufPool.Get().([]byte) defer func() { - a.bufPool.Put(buf) //nolint:staticcheck + a.bufPool.Put(buf[:0]) //nolint:staticcheck }() encoder := record.Encoder{EnableSTStorage: a.opts.EnableSTStorage} diff --git a/tsdb/agent/db_test.go b/tsdb/agent/db_test.go index f06cfa81a9..c7fc6d3c4a 100644 --- a/tsdb/agent/db_test.go +++ b/tsdb/agent/db_test.go @@ -104,6 +104,66 @@ func createTestAgentDB(t testing.TB, reg prometheus.Registerer, opts *Options) * return db } +func TestAppenderBufferResetAfterWALWriteError(t *testing.T) { + tests := []struct { + name string + prepare func(*appenderBase) + log func(*appenderBase) error + }{ + { + name: "log", + prepare: func(a *appenderBase) { + a.pendingSamples = append(a.pendingSamples, record.RefSample{Ref: 1, T: 1, V: 1}) + }, + log: func(a *appenderBase) error { + return a.log() + }, + }, + { + name: "logSeries", + prepare: func(a *appenderBase) { + a.pendingSeries = append(a.pendingSeries, record.RefSeries{ + Ref: 1, + Labels: labels.FromStrings("__name__", "test_metric"), + }) + }, + log: func(a *appenderBase) error { + return a.logSeries() + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + wal, err := wlog.New(promslog.NewNopLogger(), nil, t.TempDir(), DefaultOptions().WALCompression) + require.NoError(t, err) + require.NoError(t, wal.Close()) + + db := &DB{wal: wal, opts: DefaultOptions()} + app := &appenderBase{DB: db} + test.prepare(app) + + for range 100 { + db.bufPool.New = func() any { + return make([]byte, 0, 1024) + } + require.Error(t, test.log(app)) + + // A pool may discard buffers, especially under -race. Disable New so + // a fresh buffer cannot satisfy the assertion. + db.bufPool.New = nil + buf := db.bufPool.Get() + if buf == nil { + continue + } + require.Empty(t, buf.([]byte)) + return + } + t.Fatal("no buffer returned from pool after 100 attempts") + }) + } +} + // TestConcurrentAppendSameLabels verifies that concurrent appends for the same // label set produce exactly one series in memory and one series record in the WAL. func TestConcurrentAppendSameLabels(t *testing.T) { diff --git a/web/ui/mantine-ui/package.json b/web/ui/mantine-ui/package.json index 2e50ef5595..7d67ac50fe 100644 --- a/web/ui/mantine-ui/package.json +++ b/web/ui/mantine-ui/package.json @@ -1,7 +1,7 @@ { "name": "@prometheus-io/mantine-ui", "private": true, - "version": "0.315.0-rc.0", + "version": "0.315.0-rc.1", "type": "module", "scripts": { "start": "vite", diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index 8b15fafa33..5050372aeb 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.315.0-rc.0", + "version": "0.315.0-rc.1", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index d5d09f0653..621aa09358 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.315.0-rc.0", + "version": "0.315.0-rc.1", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package.json b/web/ui/package.json index b92e06f6be..089c553e2b 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-io", "description": "Monorepo for the Prometheus UI", - "version": "0.315.0-rc.0", + "version": "0.315.0-rc.1", "private": true, "scripts": { "build": "bash build_ui.sh --all", diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index 48dd1edfaa..88382d097c 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.315.0-rc.0", + "version": "0.315.0-rc.1", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.20.3", From 05af464634b6931015db8baf37889218cdaa458e Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 23 Sep 2026 14:00:55 +0200 Subject: [PATCH 3/6] agent: ignore unknown WAL record types Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> (cherry picked from commit 184e4a51a9008217a83e2b94f76091da62c7794d) --- tsdb/agent/db.go | 7 +- tsdb/agent/db_test.go | 159 ++++++++++++++++++++++-------------------- tsdb/head_wal.go | 3 +- 3 files changed, 88 insertions(+), 81 deletions(-) diff --git a/tsdb/agent/db.go b/tsdb/agent/db.go index e7c694f786..857528e472 100644 --- a/tsdb/agent/db.go +++ b/tsdb/agent/db.go @@ -548,11 +548,8 @@ func (db *DB) loadWAL(r *wlog.Reader, duplicateRefToValidRef map[chunks.HeadSeri // stripeSeries.exemplars in the next block by using setLatestExemplar. continue default: - errCh <- &wlog.CorruptionErr{ - Err: fmt.Errorf("invalid record type %v", dec.Type(rec)), - Segment: r.Segment(), - Offset: r.Offset(), - } + // Unknown records are ignored, enabling users to roll back. + // If this behaviour changes, update both server and agent replay. } } }() diff --git a/tsdb/agent/db_test.go b/tsdb/agent/db_test.go index c7fc6d3c4a..6bba282ed0 100644 --- a/tsdb/agent/db_test.go +++ b/tsdb/agent/db_test.go @@ -756,101 +756,110 @@ func TestPartialTruncateWAL(t *testing.T) { } func TestWALReplay(t *testing.T) { - const ( - numDatapoints = 1000 - numHistograms = 100 - numSeries = 8 - lastTs = 500 - ) + for _, unknownRecord := range []bool{false, true} { + t.Run(fmt.Sprintf("unknownRecord=%t", unknownRecord), func(t *testing.T) { + const ( + numDatapoints = 1000 + numHistograms = 100 + numSeries = 8 + lastTs = 500 + ) - s := createTestAgentDB(t, nil, DefaultOptions()) - app := s.Appender(context.TODO()) + s := createTestAgentDB(t, nil, DefaultOptions()) + if unknownRecord { + // Valid records following an unknown type must still be replayed. + require.NoError(t, s.wal.Log([]byte{255, 1, 2, 3})) + } + app := s.Appender(context.TODO()) - lbls := labelsForTest(t.Name(), numSeries) - for _, l := range lbls { - lset := labels.New(l...) + lbls := labelsForTest(t.Name(), numSeries) + for _, l := range lbls { + lset := labels.New(l...) - for range numDatapoints { - _, err := app.Append(0, lset, lastTs, 0) - require.NoError(t, err) - } - } + for range numDatapoints { + _, err := app.Append(0, lset, lastTs, 0) + require.NoError(t, err) + } + } - lbls = labelsForTest(t.Name()+"_histogram", numSeries) - for _, l := range lbls { - lset := labels.New(l...) + lbls = labelsForTest(t.Name()+"_histogram", numSeries) + for _, l := range lbls { + lset := labels.New(l...) - histograms := tsdbutil.GenerateTestHistograms(numHistograms) + histograms := tsdbutil.GenerateTestHistograms(numHistograms) - for i := range numHistograms { - _, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) - require.NoError(t, err) - } - } + for i := range numHistograms { + _, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) + require.NoError(t, err) + } + } - lbls = labelsForTest(t.Name()+"_custom_buckets_histogram", numSeries) - for _, l := range lbls { - lset := labels.New(l...) + lbls = labelsForTest(t.Name()+"_custom_buckets_histogram", numSeries) + for _, l := range lbls { + lset := labels.New(l...) - histograms := tsdbutil.GenerateTestCustomBucketsHistograms(numHistograms) + histograms := tsdbutil.GenerateTestCustomBucketsHistograms(numHistograms) - for i := range numHistograms { - _, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) - require.NoError(t, err) - } - } + for i := range numHistograms { + _, err := app.AppendHistogram(0, lset, lastTs, histograms[i], nil) + require.NoError(t, err) + } + } - lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) - for _, l := range lbls { - lset := labels.New(l...) + lbls = labelsForTest(t.Name()+"_float_histogram", numSeries) + for _, l := range lbls { + lset := labels.New(l...) - floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) + floatHistograms := tsdbutil.GenerateTestFloatHistograms(numHistograms) - for i := range numHistograms { - _, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) - require.NoError(t, err) - } - } + for i := range numHistograms { + _, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) + require.NoError(t, err) + } + } - lbls = labelsForTest(t.Name()+"_custom_buckets_float_histogram", numSeries) - for _, l := range lbls { - lset := labels.New(l...) + lbls = labelsForTest(t.Name()+"_custom_buckets_float_histogram", numSeries) + for _, l := range lbls { + lset := labels.New(l...) - floatHistograms := tsdbutil.GenerateTestCustomBucketsFloatHistograms(numHistograms) + floatHistograms := tsdbutil.GenerateTestCustomBucketsFloatHistograms(numHistograms) - for i := range numHistograms { - _, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) - require.NoError(t, err) - } - } + for i := range numHistograms { + _, err := app.AppendHistogram(0, lset, lastTs, nil, floatHistograms[i]) + require.NoError(t, err) + } + } - require.NoError(t, app.Commit()) - require.NoError(t, s.Close()) + require.NoError(t, app.Commit()) + require.NoError(t, s.Close()) - // Hack: s.wal.Dir() is the /wal subdirectory of the original storage path. - // We need the original directory so we can recreate the storage for replay. - storageDir := filepath.Dir(s.wal.Dir()) + // Hack: s.wal.Dir() is the /wal subdirectory of the original storage path. + // We need the original directory so we can recreate the storage for replay. + storageDir := filepath.Dir(s.wal.Dir()) - reg := prometheus.NewRegistry() - replayStorage, err := Open(s.logger, reg, nil, storageDir, s.opts) - if err != nil { - t.Fatalf("unable to create storage for the agent: %v", err) - } - defer func() { - require.NoError(t, replayStorage.Close()) - }() + // Replay twice to ensure unknown records do not trigger destructive WAL repair. + for range 2 { + reg := prometheus.NewRegistry() + replayStorage, err := Open(s.logger, reg, nil, storageDir, s.opts) + if err != nil { + t.Fatalf("unable to create storage for the agent: %v", err) + } - // Check if all the series are retrieved back from the WAL. - m := gatherFamily(t, reg, "prometheus_agent_active_series") - require.Equal(t, float64(numSeries*5), m.Metric[0].Gauge.GetValue(), "agent wal replay mismatch of active series count") + // Check if all the series are retrieved back from the WAL. + m := gatherFamily(t, reg, "prometheus_agent_active_series") + require.Equal(t, float64(numSeries*5), m.Metric[0].Gauge.GetValue(), "agent wal replay mismatch of active series count") - // Check if lastTs of the samples retrieved from the WAL is retained. - metrics := replayStorage.series.series - for i := range metrics { - mp := metrics[i] - for _, v := range mp { - require.Equal(t, v.lastTs, int64(lastTs)) - } + // Check if lastTs of the samples retrieved from the WAL is retained. + metrics := replayStorage.series.series + for i := range metrics { + mp := metrics[i] + for _, v := range mp { + require.Equal(t, v.lastTs, int64(lastTs)) + } + } + require.NoError(t, replayStorage.Close()) + } + }) } } diff --git a/tsdb/head_wal.go b/tsdb/head_wal.go index a4654dccae..ae33a3dce7 100644 --- a/tsdb/head_wal.go +++ b/tsdb/head_wal.go @@ -245,7 +245,8 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch } decoded <- meta default: - // Noop. + // Unknown records are ignored, enabling users to roll back. + // If this behaviour changes, update both server and agent replay. } } }() From 5241a27fe3c6983549fccc32f6e65917408c63cd Mon Sep 17 00:00:00 2001 From: Jan Fajerski Date: Fri, 25 Sep 2026 09:25:38 +0200 Subject: [PATCH 4/6] prepare 3.15.0 (#19826) Signed-off-by: Jan Fajerski --- CHANGELOG.md | 7 +++---- VERSION | 2 +- web/ui/mantine-ui/package.json | 2 +- web/ui/module/codemirror-promql/package.json | 2 +- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package.json | 2 +- web/ui/react-app/package.json | 2 +- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49fe72dc81..261fe6c8a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,7 @@ ## main / unreleased -## 3.15.0-rc.1 / 2026-09-21 -- [BUGFIX] TSDB: Avoid WAL corruption after a failed WAL write in Agent mode. #19700 - -## 3.15.0-rc.0 / 2026-09-09 +## 3.15.0 / 2026-09-24 - [CHANGE] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. Add tests to prevent regression of the fix made in #18081. #18598 - [CHANGE] PromQL: Do not register a start timestamp reset if the start timestamp hasn't changed between subsequent samples. #19454 - [CHANGE] Logging: Deprecate `--log.level`; use `runtime.log_level` configuration to supply the default level. #19511 @@ -84,6 +81,8 @@ - [BUGFIX] scrape: fix data race in `Manager.TargetsDroppedCounts` to avoid miscounting dropped targets. #19304 - [BUGFIX] scrape: fix nil histogram when native and classic histograms are mixed in one metric family. #19452 - [BUGFIX] TSDB: Fix WAL and GC log messages to emit human-readable duration strings instead of nanosecond integers. #19307 +- [BUGFIX] TSDB: Avoid WAL corruption after a failed WAL write in Agent mode. #19700 +- [BUGFIX] Agent: Ignore unknown WAL record types, to help users rolling back. #19814 ## 3.14.0 / 2026-08-17 diff --git a/VERSION b/VERSION index 4a668e99c4..f02113fe87 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.15.0-rc.1 +3.15.0 diff --git a/web/ui/mantine-ui/package.json b/web/ui/mantine-ui/package.json index 7d67ac50fe..e8c1f5460b 100644 --- a/web/ui/mantine-ui/package.json +++ b/web/ui/mantine-ui/package.json @@ -1,7 +1,7 @@ { "name": "@prometheus-io/mantine-ui", "private": true, - "version": "0.315.0-rc.1", + "version": "0.315.0", "type": "module", "scripts": { "start": "vite", diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index 5050372aeb..c3d82505d8 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.315.0-rc.1", + "version": "0.315.0", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index 621aa09358..42712865d9 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.315.0-rc.1", + "version": "0.315.0", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package.json b/web/ui/package.json index 089c553e2b..259c06c3ff 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-io", "description": "Monorepo for the Prometheus UI", - "version": "0.315.0-rc.1", + "version": "0.315.0", "private": true, "scripts": { "build": "bash build_ui.sh --all", diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index 88382d097c..562336eb67 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.315.0-rc.1", + "version": "0.315.0", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.20.3", From e42a7c9218845e6979adac0f955782aff969976e Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 21 Oct 2026 12:58:32 +0200 Subject: [PATCH 5/6] build: bump golang.org/x/net to v0.60.0 Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 37a5928c19..2b61cd1133 100644 --- a/go.mod +++ b/go.mod @@ -95,9 +95,9 @@ require ( go.yaml.in/yaml/v3 v3.0.5 go.yaml.in/yaml/v4 v4.0.0-rc.6 golang.org/x/oauth2 v0.36.0 - golang.org/x/sync v0.22.0 - golang.org/x/sys v0.47.0 - golang.org/x/text v0.41.0 + golang.org/x/sync v0.23.0 + golang.org/x/sys v0.48.0 + golang.org/x/text v0.42.0 google.golang.org/api v0.297.0 google.golang.org/genproto/googleapis/api v0.0.0-20260904194346-d0f1323225a4 google.golang.org/grpc v1.83.2 @@ -247,10 +247,10 @@ require ( go.opentelemetry.io/collector/pipeline v1.66.0 // indirect go.opentelemetry.io/proto/otlp v1.11.0 // indirect go.uber.org/zap v1.28.0 // indirect - golang.org/x/crypto v0.56.0 // indirect + golang.org/x/crypto v0.57.0 // indirect golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 // indirect - golang.org/x/net v0.58.0 // indirect - golang.org/x/term v0.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/term v0.46.0 // indirect golang.org/x/time v0.15.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20260825221802-da73d73af1c5 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect diff --git a/go.sum b/go.sum index ba01c04e5a..497dd678b5 100644 --- a/go.sum +++ b/go.sum @@ -628,8 +628,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= -golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 h1:qLvzZeaANDgyVOA8pyHCOStGlXn0rseXma+GQjeuv2g= golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -647,8 +647,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= -golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -658,8 +658,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= -golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -682,23 +682,23 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= +golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= +golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 6aaddfd82ccacf17763d1f326c5ae916cb5a6df6 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 21 Oct 2026 12:58:54 +0200 Subject: [PATCH 6/6] Release 3.15.1 Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- CHANGELOG.md | 6 +++++- Makefile.common | 2 +- VERSION | 2 +- .../remote_storage_adapter/graphite/client.go | 2 +- .../remote_storage_adapter/influxdb/client.go | 2 +- .../remote_storage_adapter/opentsdb/client.go | 2 +- notifier/alertmanager.go | 2 +- web/ui/mantine-ui/package.json | 2 +- web/ui/module/codemirror-promql/package.json | 2 +- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package.json | 2 +- web/ui/react-app/package.json | 2 +- 12 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 261fe6c8a2..c510f3b31b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## main / unreleased +## 3.15.1 / 2026-10-21 + +- [SECURITY] Container images: Update CA certificates to distrust "emSign ECC Root CA - G3" and "Comodo AAA Services root" following the compromise of eMudhra intermediate CA private keys. +- [SECURITY] Build with Go 1.27.3 to fix vulnerabilities in `net/http`, `net/textproto`, `crypto/tls` and `html/template`. +- [SECURITY] Bump golang.org/x/net to v0.60.0 to fix HTTP/2 vulnerabilities (GO-2026-6603, GO-2026-6610, GO-2026-6611, GO-2026-6612, GO-2026-6617). ## 3.15.0 / 2026-09-24 - [CHANGE] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. Add tests to prevent regression of the fix made in #18081. #18598 diff --git a/Makefile.common b/Makefile.common index 5e0edd1a5b..efc2730c16 100644 --- a/Makefile.common +++ b/Makefile.common @@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v2.13.1 +GOLANGCI_LINT_VERSION ?= v2.14.0 GOLANGCI_FMT_OPTS ?= # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. diff --git a/VERSION b/VERSION index f02113fe87..c3df54c9b8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.15.0 +3.15.1 diff --git a/documentation/examples/remote_storage/remote_storage_adapter/graphite/client.go b/documentation/examples/remote_storage/remote_storage_adapter/graphite/client.go index 61488127f6..3e8fec21ec 100644 --- a/documentation/examples/remote_storage/remote_storage_adapter/graphite/client.go +++ b/documentation/examples/remote_storage/remote_storage_adapter/graphite/client.go @@ -92,7 +92,7 @@ func (c *Client) Write(samples model.Samples) error { t := float64(s.Timestamp.UnixNano()) / 1e9 v := float64(s.Value) if math.IsNaN(v) || math.IsInf(v, 0) { - c.logger.Debug("Cannot send value to Graphite, skipping sample", "value", v, "sample", s) + c.logger.Debug("Cannot send value to Graphite, skipping sample", "value", v, "sample", s) //nolint:loggercheck // False positive for structured logging. continue } fmt.Fprintf(&buf, "%s %f %f\n", k, v, t) diff --git a/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go b/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go index 9ef5b03e72..6a3dbc5856 100644 --- a/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go +++ b/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client.go @@ -89,7 +89,7 @@ func (c *Client) Write(samples model.Samples) error { for _, s := range samples { v := float64(s.Value) if math.IsNaN(v) || math.IsInf(v, 0) { - c.logger.Debug("Cannot send to InfluxDB, skipping sample", "value", v, "sample", s) + c.logger.Debug("Cannot send to InfluxDB, skipping sample", "value", v, "sample", s) //nolint:loggercheck // False positive for structured logging. c.ignoredSamples.Inc() continue } diff --git a/documentation/examples/remote_storage/remote_storage_adapter/opentsdb/client.go b/documentation/examples/remote_storage/remote_storage_adapter/opentsdb/client.go index e2f64be5d8..09dfe8f736 100644 --- a/documentation/examples/remote_storage/remote_storage_adapter/opentsdb/client.go +++ b/documentation/examples/remote_storage/remote_storage_adapter/opentsdb/client.go @@ -77,7 +77,7 @@ func (c *Client) Write(samples model.Samples) error { for _, s := range samples { v := float64(s.Value) if math.IsNaN(v) || math.IsInf(v, 0) { - c.logger.Debug("Cannot send value to OpenTSDB, skipping sample", "value", v, "sample", s) + c.logger.Debug("Cannot send value to OpenTSDB, skipping sample", "value", v, "sample", s) //nolint:loggercheck // False positive for structured logging. continue } metric := TagValue(s.Metric[model.MetricNameLabel]) diff --git a/notifier/alertmanager.go b/notifier/alertmanager.go index a9c1e8669f..cac8937c6c 100644 --- a/notifier/alertmanager.go +++ b/notifier/alertmanager.go @@ -45,7 +45,7 @@ func (a alertmanagerLabels) url() *url.URL { // AlertmanagerFromGroup extracts a list of alertmanagers from a target group // and an associated AlertmanagerConfig. -func AlertmanagerFromGroup(tg *targetgroup.Group, cfg *config.AlertmanagerConfig) ([]alertmanager, []alertmanager, error) { +func AlertmanagerFromGroup(tg *targetgroup.Group, cfg *config.AlertmanagerConfig) ([]alertmanager, []alertmanager, error) { //nolint:revive // Preserve the existing API with an unexported return type. var res []alertmanager var droppedAlertManagers []alertmanager lb := labels.NewBuilder(labels.EmptyLabels()) diff --git a/web/ui/mantine-ui/package.json b/web/ui/mantine-ui/package.json index e8c1f5460b..44112d8b80 100644 --- a/web/ui/mantine-ui/package.json +++ b/web/ui/mantine-ui/package.json @@ -1,7 +1,7 @@ { "name": "@prometheus-io/mantine-ui", "private": true, - "version": "0.315.0", + "version": "0.315.1", "type": "module", "scripts": { "start": "vite", diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index c3d82505d8..49938ca1f0 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.315.0", + "version": "0.315.1", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index 42712865d9..d02a890146 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.315.0", + "version": "0.315.1", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package.json b/web/ui/package.json index 259c06c3ff..2a4fe93a0d 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-io", "description": "Monorepo for the Prometheus UI", - "version": "0.315.0", + "version": "0.315.1", "private": true, "scripts": { "build": "bash build_ui.sh --all", diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index 562336eb67..7b0799f21f 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.315.0", + "version": "0.315.1", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.20.3",