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.
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)
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
- command aborted by user
- --name or --identifier flag is required
- auth-key expired
- auth-key has already been used
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/4cf4b5090fe93bc8.
Report an issue: GitHub.