tailscale/tailscale · error
unimplemented on this GOOS
Error message
unimplemented on this GOOS
What it means
derp/xdp provides an eBPF/XDP-accelerated STUN server only on Linux (xdp_linux.go); xdp_default.go is the stub compiled for every other GOOS. Its NewSTUNServer (and Close, SetDropSTUN) return 'unimplemented on this GOOS' so platform-agnostic code fails loudly instead of silently misbehaving.
Source
Thrown at derp/xdp/xdp_default.go:19
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build !linux
package xdp
import (
"errors"
"github.com/prometheus/client_golang/prometheus"
)
// STUNServer is unimplemented on these platforms, see xdp_linux.go.
type STUNServer struct {
}
func NewSTUNServer(config *STUNServerConfig, opts ...STUNServerOption) (*STUNServer, error) {
return nil, errors.New("unimplemented on this GOOS")
}
func (s *STUNServer) Close() error {
return errors.New("unimplemented on this GOOS")
}
func (s *STUNServer) Describe(descCh chan<- *prometheus.Desc) {}
func (s *STUNServer) Collect(metricCh chan<- prometheus.Metric) {}
func (s *STUNServer) SetDropSTUN(v bool) error {
return errors.New("unimplemented on this GOOS")
}
func (s *STUNServer) GetDropSTUN() bool {
return true
}
View on GitHub (pinned to 6e0912f979)
Solutions
- Gate the code with a //go:build linux constraint or a runtime.GOOS check that falls back to the userspace STUN implementation.
- Build and deploy the XDP component only on Linux hosts with a kernel/dependencies that support XDP.
Example fix
// before (fails on darwin/windows: "unimplemented on this GOOS") srv, err := xdp.NewSTUNServer(cfg) // after //go:build linux srv, err := xdp.NewSTUNServer(cfg)
Defensive patterns
Strategy: validation
Validate before calling
if runtime.GOOS != "linux" {
return fmt.Errorf("xdp STUN server requires linux; build this binary for linux or use the userspace STUN implementation")
}
srv, err := xdp.NewSTUNServer(cfg) Type guard
// compile-time guard: only allow compilation of XDP paths on linux
//go:build linux
func newXDPSTUNServer(cfg *xdp.STUNServerConfig) (*xdp.STUNServer, error) {
return xdp.NewSTUNServer(cfg)
} Prevention
- Put XDP-dependent code behind //go:build linux files with a stub for other platforms.
- Provide a runtime.GOOS switch that falls back to the userspace STUN server in shared code.
- Tag XDP tests with the linux build tag so cross-platform CI doesn't hit the stub.
When it happens
Trigger: Constructing xdp.STUNServer on darwin, windows, freebsd, etc. — either directly in cross-platform code or via tests that aren't gated by build tags when run on a non-Linux host.
Common situations: Developing on a Mac against Linux production; CI build/test matrices that run the package on all GOOS; referencing derp/xdp without platform guards in shared packages.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- DeviceName is unspecified
- DstPort is outside of uint16 bounds
- tailscaled was built without DNS %q support
- {res.Error}
- {res.Err}
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/4ded23da0d42a523.
Report an issue: GitHub.