tailscale/tailscale · warning
feature not included in this build
Error message
feature not included in this build
What it means
Returned by the Tailscale localapi 'set-udp-gro-forwarding' endpoint when the binary was built without the GRO feature (buildfeatures.HasGRO == false), with HTTP 501 Not Implemented and feature.ErrUnavailable's message 'feature not included in this build'. The HasGRO build tag is only set for linux/amd64 and linux/arm64 builds; on all other platforms the endpoint is a stub.
Source
Thrown at ipn/localapi/localapi.go:825
if !h.PermitRead {
http.Error(w, "UDP GRO forwarding check access denied", http.StatusForbidden)
return
}
var warning string
if err := h.b.CheckUDPGROForwarding(); err != nil {
warning = err.Error()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(struct {
Warning string
}{
Warning: warning,
})
}
func (h *Handler) serveSetUDPGROForwarding(w http.ResponseWriter, r *http.Request) {
if !buildfeatures.HasGRO {
http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented)
return
}
if !h.PermitWrite {
http.Error(w, "UDP GRO forwarding set access denied", http.StatusForbidden)
return
}
var warning string
if err := h.b.SetUDPGROForwarding(); err != nil {
warning = err.Error()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(struct {
Warning string
}{
Warning: warning,
})
}
View on GitHub (pinned to 6e0912f979)
Solutions
- Treat HTTP 501 as a capability signal: probe and skip the call on platforms that lack GRO support
- Use a linux/amd64 or linux/arm64 build of tailscaled if you actually need to enable UDP GRO forwarding
- Gate the call on the platform: only invoke it on linux/amd64 and linux/arm64
- Update tailscaled to an official build for your platform so feature availability matches the client's expectations
Example fix
// before
if err := setUDPGROForwarding(ctx); err != nil { log.Fatal(err) }
// after
if runtime.GOOS == "linux" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64") {
if err := setUDPGROForwarding(ctx); err != nil { log.Fatal(err) }
} Defensive patterns
Strategy: type-guard
Validate before calling
// Probe capability before calling
if !(runtime.GOOS == "linux" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64")) {
return nil // endpoint unsupported here
} Type guard
func supportsGRO() bool {
return runtime.GOOS == "linux" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64")
} Try / catch
if resp.StatusCode == http.StatusNotImplemented {
// feature absent in this build; skip silently
return nil
} Prevention
- Treat 501 from localapi as a capability probe result, not an error to log loudly
- Gate platform-specific sysctl mutations on GOOS/GOARCH
- Keep client feature expectations in sync with the tailscaled build in use
When it happens
Trigger: POST /localapi/v0/set-udp-gro-forwarding against a tailscaled built for a GOOS/GOARCH without the GRO tag (e.g. darwin, windows, linux/386, linux/arm), or a custom build that dropped the tag.
Common situations: Cross-compiled tailscaled running on an unusual architecture; older or minimal custom builds; clients that unconditionally call set-udp-gro-forwarding because the corresponding check endpoint existed and returned a warning; version drift where the client is newer than the daemon.
Related errors
- {res.Error}
- {res.Err}
- debug not supported in this build
- UDP GRO forwarding check access denied
- UDP GRO forwarding set access denied
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/2019d9668b95e2d9.
Report an issue: GitHub.