GitHub
10/24/2026, 8:47 AMunsupported_platform for Windows hosts, excluded them from the library, the rollout counts and the behind gauge, and the node page showed "Upgrades are not supported on this platform yet". Windows fleets still upgraded osquery by hand.
Change
• Library: super admins can enter MSI digests: platform windows, format msi, architecture amd64. Windows MSI is amd64 only for now, because there is no verified official ARM64 asset name. The Osquery versions page offers the Windows row.
• Resolution: Resolve no longer answers unsupported_platform for windows/amd64/msi. Windows resolves like other platforms, including pins, ahead_of_target, the rollout gate and no_digest_for_target. Windows needs only the target's digest: Resolve never looks up the installed version's digest (so no no_digest_for_installed for Windows), and the route answers a target with no previous. Linux and macOS are unchanged and still need both.
• Counts: Windows hosts are part of the rollout thresholds and progress, the host list used to start a rollout, and the behind gauge. One platform rule is shared by the three queries, so thresholds, counts and Resolve see the same hosts.
• Platform rule: node rows hold osquery's platform column, which has distro names like ubuntu and centos, while the route receives the GOOS value. The node-row rule is therefore a deny-list, currently only freebsd (case-insensitive). Windows, empty and unknown platforms count.
• `rollback_unavailable`: a new reason in the upgrade reason allowlist. A host reporting it is a rejected upgrade like any other, so it pauses the rollout and appears in the rolled-back table. The existing rule applies: a rollback pauses only if it was first recorded after the last Resume.
• Node API and page: platform_unsupported is no longer true for Windows. The Windows node page shows its target, installed version and last result like other hosts, and rollback_unavailable reads "The upgrade failed and the previous version could not be restored. The host needs manual attention."
• Warnings: "If a Windows upgrade fails, the host cannot be recovered automatically. A failure pauses the rollout and the host needs manual repair." It is one shared constant, shown on the Windows node page, in the pin confirmation for a Windows host, in the Set target confirmation when the environment has Windows hosts, and next to Windows entries on the Osquery versions page. The "rolls back automatically" sentence is omitted or qualified where the warning applies.
• `windows_hosts`: the environment osquery response gains a windows_hosts count (non-deleted nodes whose platform is windows), used to decide whether the Set target warning appears.
Behavior notes
• FreeBSD nodes now leave the behind gauge, the rollout counts and the thresholds. They have no package format and Resolve already answers unsupported_platform for them, so counting them as eligible or behind was wrong. This is visible in any environment with FreeBSD nodes.
• Windows hosts running an old osctrld, or no osctrld, now count as eligible, waiting and behind, like Linux hosts in the same situation. Windows hosts need the new osctrld to upgrade.
• Resolve no longer lowercases the platform. The route already rejects anything outside ^[a-z0-9_]{1,16}$, so the difference is unreachable.
• Windows MSI entries with arm64 or 386 are rejected by the library and answered unsupported_platform.
Security and operational impact
• No new endpoints and no permission changes. The new windows_hosts field is a count behind the existing environment-admin route.
• Host-reported strings (reasons, host names) still render as plain text.
• No schema change in osctrl. The public API response adds windows_hosts, and OpenAPI is regenerated.
• Mixed versions are safe in either order. An older osctrl-tls answers unsupported_platform for Windows, so a new osctrld does nothing. An older osctrld still refuses Windows.
Validation
• go test ./... -count=1, go vet ./..., gofmt -l cmd pkg
• `golangci-lint run ./...`: 0 issues
• `make openapi-check`: clean
• Frontend: npm test (656 tests) and npm run check
• New and flipped tests cover:
• library acceptance of windows/amd64/msi and rejection of arm64 and 386
• Windows resolving target-only, with an empty or unparseable installed version, with no target digest, and with ahead_of_target and the rollout gate
• Linux still needing the previous version
• the route writing target without previous
• behind, progress and threshold counts including Windows and excluding FreeBSD, plus a parity test between the Go and SQL platform rules
• platform_unsupported for Windows, FreeBSD and distro names
• windows_hosts
• rollback_unavailable pausing the rollout, and a resent report after Resume not pausing it again
• the warnings: presence for Windows, absence otherwise, and their wording
Not tested on a real Windows host
Please run a real Windows upgrade end to end with the osctrld change, and check the node page of a Windows host. Confirm that osquery's os_version.platform is windows for your Windows hosts. The count and the warnings match that value case-insensitively.
Compatibility
Merge order does not matter, but Windows hosts upgrade only once both sides are deployed.
jmpsec/osctrlGitHub
10/24/2026, 8:53 AM