Repository navigation
Conversation
…ring matching (#1297) * fix(ledger): use AST analysis for lateral filter safety instead of string matching (#1296) The previous implementation detected $not/$or by searching for literal strings in the JSON output, which was too conservative: it disabled the LATERAL join optimization even when $not/$or didn't affect address filters (e.g. $not on metadata, single-item $or wrappers). Replace with a proper JSON AST walker that tracks structural context: - isNodeSafeForLateral: walks the tree tracking $not ancestry - nodeContainsAddressFilter: checks if a subtree has address filters - Only disables optimization when $not/$or actually impacts addresses This fixes the production case where $and(address, $not(metadata)) was incorrectly skipping the GIN index optimization. Also adds unit tests for canPushAddressFilterToLateral (17 cases) and caches the safety check result per BuildDataset call. * fix(ledger): reorder imports in utils_test.go to satisfy linter Group stdlib imports separately from third-party, with testify before formancehq per goimports ordering rules.
* chore: upgrade Go to 1.26 from pkgs-unstable Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: update go.mod to Go 1.26.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate Speakeasy client v1.758.0 Upgrade Speakeasy SDK generator to v1.758.0 and regenerate the Go client. Fix OpenAPI spec invalid $ref to parameter in schema context (sort field). Update test files and provisioner for V2ExporterConfiguration -> V2CreateExporterRequest rename, and V2RevertTransactionResponse field access in revert tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(openapi): fix invalid $ref in v2.yaml source for sort field The sort field in V2QueryParams used $ref to a parameter object in a schema context. Fix the source file (v2.yaml) to match the already fixed merged openapi.yaml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: tidy tools/provisioner go.mod Remove unused ericlagergren/decimal dependency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate API docs and tidy tools/generator - Regenerate docs/api/README.md from updated OpenAPI spec - Remove unused ericlagergren/decimal from tools/generator Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump go-libs/v4 to 56bca73d45aa (Go 1.26 fixes) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(test): buffer export body before import to fix Go 1.26 timeout Go 1.26 changed HTTP response body streaming behavior, causing the ImportLogs request to hang when directly reusing an export response body as a request body. Buffer with io.ReadAll first. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump go-libs/v4 to v4.1.3 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: fix import endpoint data race and SDK DrainBody issue - controllers_logs_import.go: fix data race between goroutine reading stream channel and main goroutine setting stream=nil. Use separate select after close(stream) instead of nil-channel trick. - pkg/client/v2.go: remove DrainBody call on ExportLogs 200 response. The response body IS the streaming payload; draining it discards the export data before callers can read it. - Revert test buffering (body is now preserved by SDK). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(import): block on errChan after stream close instead of select After EOF closes the stream, the import goroutine's result is authoritative. A two-way select could pick r.Context().Done() even when errChan is ready, losing the import result. Block directly on errChan instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(openapi): specify ExportLogs response body as application/octet-stream The export endpoint was missing content type on 200 response, causing Speakeasy to generate DrainBody() which discards the streaming payload. Also fix error response to use application/json with V2ErrorResponse. Regenerate SDK client and update test to use response.Bytes field. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate API docs after ExportLogs spec fix Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…rmance (#1311) Without this index, listing transactions without filters causes a full table sequential scan and on-disk sort of all rows before applying LIMIT. On large ledgers (12M+ rows), this results in ~200s response times. The descending index allows PostgreSQL to use an Index Scan Backward for the default ORDER BY id DESC pagination, reducing response time to milliseconds.
…ters responses (#1312) V2ListPipelinesResponse and V2ListExportersResponse had a nested cursor structure (cursor.cursor.data) instead of the expected flat one (cursor.data). The responses wrapped the CursorResponse schema in an extra cursor property with a redundant allOf, while the referenced schemas already contained the cursor structure. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Concurrent CreateLedger calls into a brand-new bucket could leave losers of the migrator's advisory-lock race without their per-ledger sequences (transaction_id_<id>, log_id_<id>) and triggers. The _system.ledgers row was inserted before b.Migrate ran. Under READ COMMITTED, migration 11's DO block (which iterates _system.ledgers to create per-ledger resources) only saw the winner's uncommitted row. Concurrent losers got ErrAlreadyUpToDate from Migrate and took the else branch, which did not call AddLedger, so their sequences were never created. The first write to such a ledger failed with `relation "<bucket>.transaction_id_N" does not exist` on the initializing→in-use state transition. Reorder: migrate or verify the bucket first, then insert the _system.ledgers row, then call AddLedger. AddLedger is now the sole owner of per-ledger setup for newly-created ledgers and runs on a freshly minted unique id, so there is no collision with the DO block and no race between concurrent creates. Add an e2e regression test that fires 10 concurrent CreateLedger calls at a fresh bucket and posts a transaction on each; reliably fails on the pre-fix code with the exact error observed in Antithesis. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add replica identity on tables without primary key * chore: upgrade go libs * fix: remove duplicate migration prefix 45-add-replica-identity The 45-add-replica-identity migration was a duplicate of 45-fix-missing-primary-keys (ADD PRIMARY KEY implies REPLICA IDENTITY). This caused the migration list to have 52 entries instead of 51, shifting indices and breaking MinimalSchemaVersion checks. Aligns migration layout with release/v2.4. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pulls in formancehq/go-libs#594 (merged) which fixes a hardcoded `idx_version_id` name collision between migrators sharing a schema. Without the fix, ledger pods running both the system migrator (`_system.goose_db_version`) and the circuit-breaker migrator (`_system.circuit_breaker_migrations`) crash at startup with: failed to create version table: failed to insert version: ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10) This was observed across multiple staging stacks after the v4 -> v5 go-libs upgrade in #1327. The fixed go-libs creates the unique index as `idx_<tableName>_version_id`, so the second migrator's CREATE UNIQUE INDEX no longer collides by name and the subsequent `INSERT ... ON CONFLICT (version_id)` succeeds. Affected DBs self-heal on next deploy with this bump - no manual SQL required. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(ci): migrate runners from Shipfox to Namespace.so * ci: cache Go and golangci-lint via nscloud-cache-action * ci: use nscloud-checkout-action for git mirror caching * ci: native multi-arch buildx via nscloud-setup-buildx-action
…no conditions (#1345) When a filter resolves to an empty string (e.g. address filter with input like "" or ":"), the query builder was still calling bun's Where() with an empty condition, producing invalid SQL: `WHERE LIMIT 16`. Guard the Where() call behind a non-empty check in buildFilteredDataset, and make filterAccountAddress return "1 = 1" instead of "" when no segments match. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
#1351) * perf(storage): remove row_number() window function from list paginator Replace `row_number() OVER (ORDER BY id DESC)` with a plain `ORDER BY` clause in both column and offset paginators. The window function forced PostgreSQL to materialise every row matching the WHERE clause before applying LIMIT, preventing early-exit on the index scan. With the plain ORDER BY, the planner places LIMIT directly on the Index Scan Backward node and stops as soon as the page is full — O(page_size) instead of O(matching_rows). Adds OrderExpression() to the Paginator interface so resource.go can propagate the correct ORDER BY through the outer CTE wrapper. Verified with EXPLAIN ANALYZE on 10 000 rows: WindowAgg node is gone, planning time drops 4× and execution time drops ~40%. The difference scales with table size; on large production ledgers this is the source of 30–50 s list-transactions queries. * test(storage): drop t.Parallel() from query plan test to avoid timing noise * test(storage): fix misleading comment on t.Parallel() removal * test(storage): assert WindowAgg presence/absence in query plan test * fix(storage): qualify ORDER BY column with dataset. after expand() joins * chore(storage): remove query plan test and apply lint fixes Drop transactions_query_plan_test.go — it served its purpose during development (verified WindowAgg is removed) but belongs in a dev branch, not the test suite. golangci-lint --fix: reflect.Ptr -> reflect.Pointer in paginator_column.go
* feat: add HTTP audit middleware Wire the go-libs audit middleware into the ledger HTTP router to capture request/response data and publish audit events via Watermill. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: use new audit package structure Update import from pkg/transport/httpserver/audit to pkg/audit/httpaudit following go-libs package restructure for protocol independence. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: sync tools go.sum with updated go-libs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: trigger CI re-run Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(deps): update security updates [security] * chore: run pre-commit
…#1357) Per-ledger controller metrics (e.g. CreateTransaction_count) carried the ledger name only as an OpenTelemetry instrumentation-scope attribute. The OTLP -> Prometheus/VictoriaMetrics translation drops scope attributes (they are not promoted to labels), so every ledger's series collapsed into one series holding the conflicting cumulative values of many ledgers. VM read the downward jumps as counter resets, turning rate() into garbage (the holes seen on Deriv prod; Mews/LTK were unaffected only because they run far fewer ledgers). Inject the ledger identity as a datapoint attribute via a metric.Meter wrapper (tracing.MeterWithAttributes) so it becomes a real label, yielding one monotonic series per (ledger, operation). The metrics meter is now a single shared "ledger" meter with no scope attributes: the per-ledger identity rides on the datapoint, which avoids retaining a distinct meter + instrument set per ledger in memory. The scope attribute is kept on the tracer, where per-ledger identity is useful and not subject to metric aggregation/cardinality. The wrapper covers all synchronous instruments (Int64/Float64 Counter, UpDownCounter, Histogram, Gauge); asynchronous/observable instruments are documented as not covered. Constraint: OTLP->Prometheus translation drops instrumentation-scope attributes Rejected: Thread the label through TraceWithMetric at ~30 call sites | churn + easy to forget on new metrics Rejected: Promote scope attributes in the OTLP collector | makes app correctness depend on external infra config; global cardinality blast radius Confidence: high Scope-risk: moderate Directive: This turns `ledger` into a real label across ~27 controller histograms; per-ledger cardinality grows with ledger count. If a stack runs very many ledgers, gate this behind a flag or drop the per-ledger dimension instead of promoting it. Not-tested: end-to-end OTLP export shape against a real VictoriaMetrics ingest Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Preserve ledger state tracking, sequence restoration, and transactional event buffering for atomic bulks after log import.
* docs(openapi): describe the schema fields in the spec The Ledger spec declared its account, transaction, volume, log and exporter schemas without saying what any of the fields mean. Add descriptions to v1 and v2, re-merge the root spec, and regenerate the API reference. * fix(openapi): wrap described $ref schemas in allOf V2LogDataRevertedTransaction's two properties carried a description alongside a bare $ref. This spec is OpenAPI 3.0.3, where $ref siblings are ignored, so neither description reached generated docs or SDK comments. Wrapping each in a single-member allOf puts the description where tooling reads it. These two predate this PR, but they are the same defect the PR exists to fix, in a file it already touches. A one-member allOf validates identically to the bare $ref, so shapes are unchanged. * fix(openapi): regenerate the bundled spec and keep the bi-temporality link intact * chore(sdk): regenerate the Go client for the new spec descriptions Runs the generator the Dirty check runs, so pkg/client carries the field descriptions added to the spec. gen.lock's docChecksum now matches the md5 of openapi.yaml, which is what keeps the two in sync.
…-1872) (#1779) The accounts_metadata history trigger dates each revision at the account row's updated_at, and DeleteAccountMetadata removed the key without touching it, so the delete's revision inherited the previous write's instant. Every point-in-time read at or after a set then resolved to the delete's revision: the key was erased retroactively, and the interval during which it was genuinely visible became unobservable through /accounts, account counts, aggregated balances and /volumes. The delete now carries its own instant, exactly like the transaction-metadata delete: the log date on the replay path, the store's transaction_date() when none is given.
…1841) V2Metadata is shared, so the bi-temporal/point-in-time sentence added in #1730 was inherited by V2CreateLedgerRequest, V2Ledger and V2UpdateLedgerMetadataRequest. Ledger metadata is configuration read via GET /v2 and GET /v2/{ledger} and written via PUT /v2/{ledger}/metadata, none of which take a pit parameter — point-in-time history applies to account and transaction metadata only. The shared schema description is now generic and the bi-temporal sentence sits on V2Transaction.metadata via the allOf pattern used elsewhere in the spec. V2Account.metadata already declared it inline, correctly scoped. Reported by shipfox-ai on #1730, after that PR had been approved.
…cient funds error (#1808) * fix kept * test(machine): restore compiler tests, update TestDestinationInOrder bytecode Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…ts address (#2063) * test(machine): reproduce save dropping its expression's right operand `save <monetary expression> from @acc` reserves only the expression's left-hand operand: alice has 100 save [COIN 50] - [COIN 40] from @alice reserves 50, not 10 save [COIN 90] + [COIN 5] from @alice reserves 90, not 95 No error and no warning — just the wrong amount reserved, which the following `send [COIN *]` then makes visible. The two controls in the test (a plain monetary, and `save [COIN *]`) already pass, so this isolates the arithmetic path rather than `save` generally. These tests are expected to fail; the fix follows. * fix(machine): evaluate save's monetary expression instead of taking its address VisitSaveFromAccount asked VisitExpr for an address and pushed that. VisitExpr has two modes, and only the push one emits arithmetic: if push { ... OP_MONETARY_SUB } return machine.TypeMonetary, lhsAddr, nil So on the address path no operator was emitted and the address handed back was the left operand's. `save [COIN 50] - [COIN 40]` compiled to exactly the same bytecode as `save [COIN 50]`. Push the monetary instead, and drop the PushAddress that went with it. The asset form of `save` keeps the address path — `[COIN *]` takes an asset, which has no arithmetic — and so does the account operand. `send` was never affected: VisitMonetary takes the address only to derive the asset for OP_ASSET and setNeededBalances, then evaluates the expression properly with VisitExpr(mon, true). Net effect on the reproducers from the previous commit: all pass.
* test(machine): reproduce balance() resource collisions ResolveResources registers balance() requests under the resolved account address, which is not unique. Three ways to collide, all ending in a resource left with a nil amount that panics on first use: 1. two resources resolving to the same ACCOUNT ($acc and @src) 2. two resources resolving to the same ASSET ($ass and USD) 3. two assets needed for the SAME account (USD and EUR on @src) All three are reachable from plain numscript and reproduce against the real postgres store, not just StaticStore. Also fixes StaticStore.GetBalances, which re-made its per-account map inside the asset loop and so could only ever return one asset per account. Without this, case 3 is untestable: it would fail on the test double rather than on the bug. These tests are expected to fail; the fix follows. * fix(machine): key balance() requests by resource index ResolveResources registered each balance() request under the resolved account address: m.UnresolvedResourceBalances[address] = idx An account address is not unique across resources, so the second registration overwrote the first and its resource was never assigned a balance, keeping a nil amount that panicked on first use. Key the map by the resource index instead. Every balance() call allocates exactly one resource, so the index is unique by construction and none of the three collisions can occur. This also removes the need for the reverse account/asset lookup map, whose nested entries existed only to undo the collapse, so the assignment loop now iterates the balance resources and takes each one's balance rather than iterating returned balances and searching for the resource that wanted it. Net effect on the three reproducers from the previous commit: all pass. * fix: remove dedup * test: update test
* fix(storage): clean up migration temporary tables * fix(storage): restrict migration cleanup to temporary tables Qualify migration-owned temporary tables with pg_temp so cleanup preserves permanent tables with the same names. Cover fresh and stale temporary-table sessions in regression tests and document the migration lifecycle. --------- Co-authored-by: Maxence Maireaux <maxence@formance.com>
* docs(openapi): document bigint response header * test(api): cover bigint response header * chore(client): regenerate SDK for bigint header --------- Co-authored-by: Maxence Maireaux <maxence@formance.com> Co-authored-by: Codex <codex@formance.com>
Co-authored-by: Codex <codex@formance.com>
* feat(tracing): skip OTLP error recording for selected errors Add TraceOption with SkipErrorRecordingIf and WithSpanStartOptions so Trace and TraceWithMetric can omit otlp.RecordError for expected cases (e.g. not found on ReadLogWithIdempotencyKey). Migrate ImportLog span options to WithSpanStartOptions. Inline the InsertTransaction metric finalizer into the traced callback because TraceWithMetric now takes trace options as its trailing variadic. Made-with: Cursor Signed-off-by: Sylvain Rabot <sylvain@formance.com> * test(tracing): cover SkipErrorRecordingIf and WithSpanStartOptions Assert that a skipped error is still returned but leaves the span status Unset with no error event, that wrapped errors match, that predicates compose with OR, and that span start options accumulate. Promotes go.opentelemetry.io/otel/sdk to a direct dependency for sdk/trace/tracetest; version unchanged. Confidence: high Scope-risk: narrow Signed-off-by: Sylvain Rabot <sylvain@formance.com> --------- Signed-off-by: Sylvain Rabot <sylvain@formance.com>
Contributor
Author
ℹ Artifact update noticeFile name: deployments/pulumi/go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
File name: go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
File name: tools/generator/go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
File name: tools/provisioner/go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
|
auto-merge was automatically disabled
October 13, 2026 12:21
Pull request was closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
v0.4.0->v0.4.1v0.58.0->v0.60.0github.com/moby/sys/user has a possible DoS via unbounded parsing of user and group database files
CVE-2026-61801 / GHSA-mjcv-p78q-w5fw
More information
Details
A denial-of-service (DoS) vulnerability exists in
github.com/moby/sys/userbefore v0.4.1 when parsing specially crafted user or group database files. An attacker able to supply a malicious/etc/passwdor/etc/group-style file may cause excessive memory consumption, potentially resulting in process termination due to Out Of Memory (OOM) conditions.This issue is related to containerd [CVE-2026-47262] / GHSA-jpcc-p29g-p8mq, which describes one practical exploitation path through processing untrusted container image content. Applications using
github.com/moby/sys/userto parse untrusted user or group database files may be similarly affected.Impact
github.com/moby/sys/userversions before v0.4.1 do not place sufficient limits on entries while parsing user and group database files. A specially crafted file may cause excessive memory consumption, potentially leading to process termination due to Out Of Memory (OOM) conditions.Applications that use
github.com/moby/sys/userto parse user-supplied or otherwise untrusted/etc/passwdor/etc/groupfiles may be affected. The severity depends on whether an attacker can influence the contents of files being parsed.Patches
This issue is fixed in
github.com/moby/sys/userv0.4.1. Users should upgrade to v0.4.1 or later.Workarounds
Avoid parsing attacker-controlled
/etc/passwdor/etc/group-style files with affected versions ofgithub.com/moby/sys/user.Applications that must process untrusted user or group database files should validate and limit accepted input before parsing. Upgrading to v0.4.1 or later is the recommended remediation.
References
github.com/moby/sys/user: https://github.com/moby/sys/user/commit/210d32ba2bcb4544ee968c7f31249fe59796e60bSeverity
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Double flow control refund on HTTP/2 server streams in net/http
CVE-2026-78663 / GO-2026-6612
More information
Details
The HTTP/2 server can refund connection-level flow control twice for the same data: Once when a client resets a stream (refunding data for any sent-but-unread portion of the stream), and again when a request handler reads the buffered data. A malicious client can exploit this to bypass the configured connection-level flow control limit (MaxReceiveBufferPerConnection). Total buffered data is still limited by the concurrent stream limit and stream-level flow control.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
HTTP/2 transport accepts malformed framing-related headers in net/http
CVE-2026-78660 / GO-2026-6610
More information
Details
Historically, we have been rather lax about malformed framing-related headers in our HTTP/2 implementation, as they cannot interfere with HTTP/2 framing. However, this makes it possible for our HTTP/2 implementation to forward responses containing such headers to an HTTP/1 client when acting as a reverse proxy. If the HTTP/1 client also does not behave strictly enough, this can result in response smuggling.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
Excessive CPU consumption from repeated initial window changes in net/http
CVE-2026-78669 / GO-2026-6611
More information
Details
A malicious HTTP/2 peer can cause excessive CPU consumption in the client or server by opening a large number of streams and then sending many small SETTINGS frames containing SETTINGS_INITIAL_WINDOW_SIZE values.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
HTTP/2 server memory exhaustion due to Trailer headers in net/http
CVE-2026-78659 / GO-2026-6603
More information
Details
When "Trailer" headers are sent by a client, the HTTP server internally uses the header values to populate the Request.Trailer map passed to the server handler. Because Request.Trailer is a map, each entry incurs memory overhead. For HTTP/2 servers, a malicious client can exploit this by sending a "Trailer" header that declares a large number of fields, causing the server to allocate a disproportionate amount of memory while bypassing Server.MaxHeaderValueCount and Server.MaxHeaderBytes limits. This exploit is not applicable for HTTP/1 servers, which do not support multiplexing a large number of requests over one TCP connection, and whose Server.MaxHeaderBytes are calculated differently.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
HTTP/2 server crash due to HPACK encoder race in net/http
CVE-2026-97032 / GO-2026-6617
More information
Details
HTTP/2 servers could end up crashing due to inadvertently modifying its HPACK encoder concurrently. This happens because the server modifies the HPACK encoder from two goroutines without synchronization: one uses the encoder to encode a HEADERS frame as part of a response sent to a client and the other modifies the encoder's table size when handling a SETTINGS frame containing SETTINGS_HEADER_TABLE_SIZE that a client sends. A malicious client can repeatedly send a request while changing the header table size to crash the server.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
Configuration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.
This PR has been generated by Renovate Bot.