-
v0.31.2
Stableaudit / docs-site-audit (push) Successful in 23saudit / bun-audit (web) (push) Successful in 24saudit / bun-audit (sdk) (push) Successful in 26saudit / pnpm-audit (push) Successful in 19saudit / bun-audit (plugin-kit) (push) Successful in 26saudit / cargo-audit (push) Failing after 40sci / web (push) Successful in 1m21sci / docs-site (push) Successful in 1m13sci / bun-nix (push) Successful in 16sci / docs-drift (push) Successful in 21saudit / license-gate (push) Successful in 4m57saudit / miri (push) Successful in 6m17saudit / c-abi-asan (push) Successful in 6m24sandroid-screenshots / screenshots (push) Successful in 1m54sci / rust-arm64 (push) Successful in 1m38sci / rust (push) Successful in 8m29sandroid / android (push) Successful in 11m48sarch / build-publish (push) Successful in 9m23slinux-client-screenshots / screenshots (push) Successful in 4m53ssbom / sbom (push) Successful in 33sweb-screenshots / screenshots (push) Successful in 6m46sdecky / build-publish (push) Successful in 48sdocker / builders-arm64cross (push) Successful in 10sdocker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 20sdocker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 13sdocker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 15sdocker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 14sdocker / builders (ci/flatpak-ci.Dockerfile, punktfunk-flatpak-ci) (push) Successful in 11sdocker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Successful in 8sdocker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 16sdocker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 13sdocker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 17sdocker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m31sdocker / deploy-docs (push) Successful in 17snix / flake (push) Successful in 22m13sdeb / smoke-install (push) Successful in 2m52sdeb / build-publish (push) Successful in 5m12sdeb / build-publish-host (push) Successful in 5m39sdeb / build-publish-gamescope (push) Successful in 1m5sdeb / build-publish-client-arm64 (push) Successful in 2m42srpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 18m49sapple / distribute (push) Successful in 13m6sapple / swift (push) Successful in 2m4srpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 21m22sapple / screenshots (push) Successful in 9m40swindows-host / package (push) Successful in 13m30swindows-host / canary-manifest (push) Skippedwindows-host / winget-source (push) Successful in 28swindows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 5m57swindows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 9m45sflatpak / build-publish (push) Failing after 8m56sreleased this
2026-08-21 20:50:53 +00:00 | 6874 commits to main since this releaseWire-compatible with 0.31.x — everything you have already paired keeps working, and you can update one side at a time. Nothing here changes how a host and a client agree on what to send each other, so an old client on a new host, or the other way round, streams exactly as it does today.
This is a fix release, and most of it continues the hunt 0.31.1 started: a stream that connects, reports itself perfectly healthy at every gauge, and shows you a black screen. Two more causes end here, and both are about which of your host's addresses it used — video that left the host by whichever network connection the machine happened to prefer rather than the one your client actually dialled, and a host that started up faster than its own network and then spent the rest of the day telling everyone to connect to an address that only ever means "this machine". The other half is Windows security: the firewall rules Punktfunk installs named ports but not programs, which left those ports open to anything running on that PC — they name Punktfunk now, and that is the one change here that can affect another program on the same machine. On Android, the controller fix from 0.31.1 turned out to be firing on controllers that never needed it, breaking buttons that had been correct all along.
TL;DR
- A host with two ways to reach your client streamed into a black screen. Ethernet and Wi-Fi both connected, or a VPN adapter installed, was enough: the video left by whichever one the machine preferred, and your client discarded every packet of it. Nothing else about the session was wrong, which is exactly why it was so hard to see.
- A host that started before its network was ready never recovered. It advertised an address meaning "this machine", so clients listed it and could not connect to it, Moonlight-compatible sessions could not stream, and Wake-on-LAN silently stopped working. Restarting the host was the only cure; now there is nothing to cure.
- Windows: Punktfunk's firewall rules were open to every program on your PC. They named only port numbers, so any program — with no administrator rights and no prompt — could take one of those ports and be reachable from your network through a rule meant for Punktfunk. Read Before you update: one thing on that machine may now need a rule of its own.
- Android: 0.31.1's controller fix broke controllers that were already correct. On a GameSir G8+ and an Xbox Elite Series 2 over Bluetooth, X answered Y, Y answered the left shoulder, and both shoulders answered menu buttons.
- Your host now follows its own address when it changes — a new lease from your router, or a machine moved between Wi-Fi and Ethernet — instead of announcing the address it had at startup forever.
Before you update
- Windows hosts: run the installer rather than replacing the program by hand. The firewall fix rewrites the rules Punktfunk installs, and that happens in the host's own service-install step, which the installer runs for you on every update. If you run the host some other way, run
punktfunk-host service installonce as an administrator. Skipping it leaves the old wide-open rules in place; nothing on the client side needs doing. - Windows hosts: something else on that machine may need its own firewall rule now. Punktfunk's rule for the discovery port (5353) used to be open to every program, so anything else on that PC that answers discovery — another streaming host, a media server, a printer or scanner utility — could have been reachable through Punktfunk's rule without ever having one of its own. That ends with this release. If something else on the machine stops being discoverable after you update, give it its own rule. The installer prints a note saying exactly this while it works.
Improved
- Your host keeps up with its own address instead of freezing it at startup. The address a host publishes for clients to dial was worked out once, when the host process started, and then never looked at again. Now it is re-read as things change and the published address is updated to match — so a new lease from your router, or a laptop host carried from Wi-Fi to Ethernet, no longer leaves your clients dialling somewhere the host has not been for hours. This is the general form of the cold-boot fix below, and it covers the cases nobody had got round to reporting yet.
- When a stream does go black, the host's log now tells you the truth about it. The message it printed used to name a cause with real confidence — and was wrong often enough to send people to the wrong place entirely, including at least one investigation that went to the firewall while the actual fault was the network card. It no longer asserts a cause it cannot know, and it now records which network connection the video is actually leaving by, and says so plainly when that is not the one the client arrived on. That single line is what turns the black screen above from a mystery into something a log answers.
Fixed
- A host with more than one live path to your client sent the video down the wrong one, and you got a black screen with every indicator green. Two network connections up on the same network — the very common Ethernet-and-Wi-Fi-both-on — or a VPN or overlay adapter that claims to know a better route, and the host let the machine choose which one the video left by. That choice was made with no reference at all to how your client had reached it. Your client only listens for video from the address it dialled, so it threw away everything arriving from the other one, in the part of the system that counts nothing and reports nothing. Meanwhile the connection was made, sound and controller input flowed perfectly, and the host's own loss figure sat at zero — because loss is measured over packets that arrived, and none did. The host now sends the video from the same address the client reached it on.
- A host that started before its network was ready advertised itself as unreachable, and stayed that way until it was restarted. Cold-booting a machine is a race, and the host wins it: it starts without waiting for the network, asks which address it should publish, gets no answer because there is no network yet, and falls back to the address that means "this machine and nothing else". Then it kept that answer for the entire life of the process. Everything that reads that address broke together — the host appeared in your client's list but could not be connected to, Moonlight-compatible sessions were handed the same useless address after launching a game, Wake-on-LAN quietly stopped working because the host could no longer identify the network hardware to record for it, and the web console displayed the wrong address to anyone who looked. Users found the workaround themselves, which was to restart the host once the machine had settled. The host now refuses that fallback answer entirely: if the usual method cannot say which address to use, it takes the first real network address it can find, which exists as soon as the network card is configured — well before the machine finishes working out how to route anything.
- Windows: the firewall rules Punktfunk installs opened those ports to every program on the machine, not to Punktfunk. Each rule named a port and nothing else, and a rule like that admits whatever is listening on that port — Punktfunk or otherwise. Nothing about it required administrator rights to exploit: taking a high-numbered port on Windows needs no privileges at all, so any program that started first could sit on one of Punktfunk's ports and be reachable from your whole network. Worse, it happened without any of the usual signs, because the pop-up asking whether to let a program communicate on your network is precisely what a matching rule suppresses — Punktfunk's rule was answering that question on another program's behalf. Every rule now names the program that is genuinely meant to be listening on it, and keeps the port restriction as well, so both must match. The affected ports were the streaming, discovery, management and console ports. If Punktfunk cannot work out its own location on disk it keeps the old broader rule rather than leaving you with no rule at all, since a rule that is too generous still streams and a missing one is a black screen.
- Android: controllers that had always worked started pressing the wrong buttons. This is a regression from 0.31.1, reported the same day on a GameSir G8+ and an Xbox Elite Series 2: X answered Y, Y answered the left shoulder, and the two shoulder buttons answered menu buttons, with everything else correct. 0.31.1 fixed controllers Android has no layout file for by reading each button's position in the controller's own report instead of trusting Android's guess — the right fix, applied to too many controllers. It decided which controllers needed it by asking what the device claimed to have, and that claim turns out to be true of any controller with six or more buttons, including every controller that was already perfectly correct. So it corrected pads that needed no correcting, and moved their buttons off the marks. It is now decided on the triggers instead: a controller that describes its triggers properly is one Android has a real layout for, and it is left completely alone — no correction to its buttons or its sticks. That is the same signal Moonlight uses for the same decision, and it matches the reports precisely, down to the fact that the very same model needed correcting on a Fire TV and was broken by it here: an Xbox Wireless Controller describes its triggers one way after a firmware update and the other way before it, and only the older one was ever wrong.
Known issue
- A DualSense with a dead Triangle button is not fixed here. It was reported alongside the two controllers above and looks related, but it is not the same fault — Triangle reaching neither the stream nor Punktfunk's own controller display is a different failure from a button arriving as the wrong one, and nothing in the fix above produces it. The Connected controllers page prints exactly what each press reports; that line from an affected pad is what will pin it down.
Thanks
Every fix in this release came from someone reporting what actually happened rather than what they assumed. Both black-screen causes were found in field logs from hosts that looked entirely healthy — and the firewall hole was reported by a user on the same day, immediately after the first of those fixes cleared their black screen and left them looking at the rules. The Android controller regression came back within a day of the release that caused it, from two people who named which button answered which, which is the difference between a report that can be fixed and one that can only be believed. Thank you.
For developers
Protocol, ABI, driver and embedder detail — including the version table — is in CHANGELOG.md.
The short version: nothing versioned moves at all. The streaming protocol, the embedding interface, the driver protocol, the gamepad channel and the add-on contract are exactly where 0.31.1 left them, no message or function changed shape, and no header, package or plugin needs rebuilding, re-pairing or re-publishing in any direction. Two things worth knowing: on Windows the firewall rules provisioned at install are now scoped to the executable that listens on each port, which is the one change here that can affect another program on the same machine; and the host's reported address in the management API is now read fresh on every request instead of being fixed for the life of the process, so poll it rather than caching it.
Downloads