Repository navigation
kubefwd-v1.25.17
kubefwd v1.25.17
Warning
Superseded by v1.25.18. Do not install this version.
v1.25.17 shipped with known vulnerabilities in golang.org/x/net. Five HTTP/2 advisories are reachable from kubefwd: GO-2026-6603, GO-2026-6610, GO-2026-6611, GO-2026-6612 and GO-2026-6617. It also has unreachable advisories in x/crypto and x/text. v1.25.18 fixes all of them and includes every fix below.
This release fixes three forwarding bugs:
- A goroutine and memory leak on idle forwards across sleep and wake.
- Forwards that kept pointing at the old port or pod after a Service was updated in place.
- Forwards that flapped when the API server interrupted a pod watch.
It also fixes a vulnerability in golang.org/x/text that kubefwd's own code reaches. It moves to the Kubernetes 0.37 client libraries and brings in four months of dependency updates.
The fixes below are all included in v1.25.18. Install v1.25.18 instead.
Bug fixes
Idle forwards no longer leak goroutines and memory (#622, refs #614)
Reported by @avni-ef: memory grew from 74 MB to 1.48 GB over two days on a machine that slept and woke.
kubefwd keeps each forward's connection alive by pinging it every 30 seconds. Stopping the pinger sent a signal that gave up after 100 ms. If a ping was in flight on a connection that died during sleep, which can take up to 30 seconds, the signal was missed. That pinger then kept running against a dead connection forever, and every reconnect added another one.
Now:
- Stopping is reliable. The stop signal is a closed channel, which a pinger sees even when it is busy at that moment, so stopping never times out.
- Pinging stops on every exit path from a forward, including early errors.
- A pinger also ends on its own when its connection closes.
- A pinger never opens a new stream on a connection that is shutting down.
A regression test reproduces the leak against the old code. The approach comes from #619 by @AdamMagued.
The report also shows a second, smaller leak of SPDY connection goroutines. Its root cause is in the Kubernetes streaming library, not in kubefwd. This release makes it less likely to happen, and #614 stays open to track it.
In-place Service updates now rebuild forwards (#617, fixes #615)
Contributed and reported by @idan-rahamim-lendbuzz.
When a Service changed in place, kubefwd kept forwarding to the old target. This happened with a Helm upgrade that moved a port to a sidecar, a changed targetPort, or a changed selector. Before, kubefwd only noticed a change in the number of ports, and even then it resynced from its stale copy of the Service. The only fix was a restart.
Now:
- Port or selector changes: kubefwd compares the Service's ports and selector, stops the affected forwards, waits for their cleanup to finish, and rebuilds them from the new spec. A
targetPortchange and a selector change that moves the Service to different pods both take effect within about a second. - Selector removed: the Service's forwards stop.
- Selector added: a Service that previously had no selector, and was skipped, gets forwarded.
- Status-only and metadata-only updates are still ignored.
- TUI: shows a
ServiceUpdatedevent for each rebuild.
Two related fixes come with it. A finishing forward no longer removes a replacement registered under the same key. Pod syncs are serialized, so a rebuild can't interleave with a reconnect or resync.
Tested on a KIND cluster against v1.25.16:
| Check | v1.25.16 | v1.25.17 |
|---|---|---|
| Initial forward | pass | pass |
targetPort 5678 → 5679 |
still hits 5678 | follows to 5679 |
| Selector moved to a different deployment | still hits the old pod | follows to the new pod |
/etc/hosts cleaned up on exit |
pass | pass |
A rebuild can give the Service a new loopback IP. The hostname follows it, but connections open during the rebuild are dropped.
Pod watch interruptions no longer flap forwards (#618, fixes #616)
Contributed and reported by @idan-rahamim-lendbuzz.
While waiting for a Pending pod to become Running, kubefwd used a single watch. If the API server sent an ERROR event or closed the stream, kubefwd treated that as a failed forward: it tore the forward down and backed off. On a busy cluster this made new forwards flap for about 25 seconds at startup.
Now an interrupted watch is retried after one second from a fresh read of the pod. The --timeout deadline and the stop signal work as before. The API server's error message is now logged, so the cause is visible.
Security
golang.org/x/text(GO-2026-5970), now 0.40.0 (#563). Invalid input could cause an infinite loop. This one was reachable from kubefwd's own code: the MCP HTTP client callshttp.Client.Do, which reaches the vulnerable normalization code. It affects v1.25.16, which shippedx/text0.34.0. Dependabot never flagged it;govulncheckfound it.golang.org/x/net(GO-2026-5942), now 0.57.0, andgolang.org/x/crypto(GO-2026-5932), now 0.54.0 (#563 and later updates).- Integration-test module only, not part of the binary (#560, #563):
- Moved from
github.com/docker/dockerto themoby/mobyAPI and client modules by upgradingtestcontainers-goto 0.43.0. This clears five Docker daemon advisories. - Bumped
x/crypto, which clears 13 more alerts. - Fixed the integration module so it builds again.
- Moved from
- Docs toolchain only (#560, #620): Pygments 2.20.0 (ReDoS) and urllib3 2.8.0 (GHSA-8988-9cw3-xx77, GHSA-vxq7-64xx-v4gw, GHSA-gh4c-6fx4-qh6g).
Dependency updates
| Module | v1.25.16 | v1.25.17 |
|---|---|---|
k8s.io/api, apimachinery, client-go, cli-runtime, kubectl, streaming, component-base |
0.36.2 | 0.37.1 |
github.com/modelcontextprotocol/go-sdk |
1.6.1 | 1.8.0 |
charm.land/bubbletea/v2 |
2.0.7 | 2.0.9 |
charm.land/bubbles/v2 |
2.1.0 | 2.2.1 |
charm.land/lipgloss/v2 |
2.0.4 | 2.0.6 |
github.com/evertras/bubble-table |
0.22.3 | 0.23.0 |
github.com/sirupsen/logrus |
1.9.4 | 1.10.2 |
golang.org/x/sys |
0.46.0 | 0.48.0 |
golang.org/x/net |
0.51.0 | 0.57.0 |
golang.org/x/crypto |
0.48.0 | 0.54.0 |
golang.org/x/text |
0.34.0 | 0.40.0 |
golang.org/x/oauth2 |
0.35.0 | 0.36.0 |
Indirect dependencies were updated to match. Binaries are built with Go 1.26.9.
CI, build and supply chain
-
Build provenance: the release workflow now uses GitHub's native artifact attestation (
actions/attest) for SLSA build provenance (#529, #537). This fixes the provenance step that failed in the v1.25.16 release run. Each archive and.mcpbbundle has a sigstore bundle, and each archive has an SBOM. -
Action updates:
actions/checkout7.0.0 (#530)actions/setup-go6.5.0 (#535)actions/setup-python6.3.0 (#534)goreleaser/goreleaser-action7.2.3 (#531)golangci/golangci-lint-action9.3.0 (#532)docker/login-action4.4.0 (#545)docker/setup-buildx-action4.2.0 (#543)github/codeql-action4.38.2codecov/codecov-action7.1.1anchore/sbom-action0.24.3
All actions stay pinned to full commit SHAs (#553, #559, #579, #591, #602, #620).
Verify this release
gh attestation verify kubefwd_Darwin_arm64.tar.gz --repo txn2/kubefwdChecksums are in kubefwd_checksums.txt, which also has a sigstore bundle.
Install / upgrade
# Homebrew (macOS / Linux)
brew install txn2/tap/kubefwd
brew upgrade kubefwd
# Docker
docker pull txn2/kubefwd:v1.25.17 # also :v1.25.17_alpine-3, :v1.25.17_ubuntu-24.04
# Or download a binary or package (deb, rpm, apk) for your platform from the assets below.Run it (requires root for /etc/hosts and loopback aliases):
sudo -E kubefwd svc -n <namespace> --tuiThanks
- @idan-rahamim-lendbuzz for #615, #616, #617 and #618: two clear bug reports, each followed by a well-tested fix.
- @avni-ef for the detailed leak report in #614, with goroutine dumps.
- @AdamMagued for the approach in #619.
Full changelog: v1.25.16...v1.25.17