juanfont/headscale · error
MOCKOIDC_PORT not defined
Error message
MOCKOIDC_PORT not defined
What it means
Returned as HTTP 400 during the noise handshake when the client's declared capability version is below capver.MinSupportedCapabilityVersion; the message string comes from unsupportedClientError(version) ('unsupported client version: %s (%d)' with a human-readable Tailscale version and the numeric capver). The server also logs an 'unsupported client connected' error including node and machine keys, so you can identify which peer was rejected.
Solutions
- Upgrade the connecting tailscale client to at least capver.TailscaleVersion(capver.MinSupportedCapabilityVersion) for your headscale build (check the log line's minimum_version field), then 'tailscale down && tailscale up'.
- Find the offending machine from the log's node.key/machine.key fields and target its upgrade first.
- If you cannot upgrade a client immediately, pin headscale to the last release whose capver floor that client meets.
- For custom clients, report a capability version >= the minimum in the handshake.
Example fix
# before (old client rejected with 400 unsupported client version) $ tailscale version # e.g. 1.32.0 # after # Debian/Ubuntu example: sudo apt update && sudo apt install tailscale # or upstream: curl -fsSL https://tailscale.com/install.sh | sh tailscale up --login-server https://headscale.example.com
Defensive patterns
Strategy: validation
Validate before calling
// Check client capver before registering (mirrors isSupportedVersion).
clientVer := tailcfg.CurrentCapabilityVersion
if clientVer < capver.MinSupportedCapabilityVersion {
return fmt.Errorf("client capver %d too old; need >= %d (%s)",
clientVer, capver.MinSupportedCapabilityVersion,
capver.TailscaleVersion(capver.MinSupportedCapabilityVersion))
} Prevention
- Upgrade the tailscale fleet before (or together with) headscale upgrades.
- Track MinSupportedCapabilityVersion changes in headscale release notes.
- Fleet-monitor the 'unsupported client connected' log lines to catch stragglers by node/machine key.
When it happens
Trigger: An old tailscaled (e.g. anything older than the minimum supported release, such as 1.x versions predating the floor) running 'tailscale up' against this headscale; a vendored/forked client reporting a low capability version; embedded devices shipping stale tailscale binaries.
Common situations: Upgrading headscale past a capver floor (each headscale release raises MinSupportedCapabilityVersion) while fleets still run old tailscale clients; long-lived IoT/routers never updated; OS-distro tailscale packages that lag far behind upstream.
Related errors
- MOCKOIDC_CLIENT_SECRET not defined
- allocating IPs
- auth ID has invalid length
- auth ID has invalid prefix
- auth-key expired
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/4cf4b5090fe93bc8.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/headscale/cli/mockoidc.go:23
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"os"
"strconv"
"time"
"github.com/juanfont/headscale/hscontrol/util/zlog/zf"
"github.com/oauth2-proxy/mockoidc"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
var (
errMockOidcClientIDNotDefined = errors.New("MOCKOIDC_CLIENT_ID not defined")
errMockOidcClientSecretNotDefined = errors.New("MOCKOIDC_CLIENT_SECRET not defined")
errMockOidcPortNotDefined = errors.New("MOCKOIDC_PORT not defined")
errMockOidcUsersNotDefined = errors.New("MOCKOIDC_USERS not defined")
)
const refreshTTL = 60 * time.Minute
var accessTTL = 2 * time.Minute
func init() {
rootCmd.AddCommand(mockOidcCmd)
}
var mockOidcCmd = &cobra.Command{
Use: "mockoidc",
Short: "Runs a mock OIDC server for testing",
Long: "This internal command runs a OpenID Connect for testing purposes",
RunE: func(cmd *cobra.Command, args []string) error {
err := mockOIDC()
if err != nil {View on GitHub (pinned to 565fd254d0)