{"record":{"id":"4cf4b5090fe93bc8","repo":"juanfont/headscale","slug":"mockoidc-port-not-defined","errorCode":null,"errorMessage":"MOCKOIDC_PORT not defined","messagePattern":"MOCKOIDC_PORT not defined","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/headscale/cli/mockoidc.go","lineNumber":23,"sourceCode":"\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/juanfont/headscale/hscontrol/util/zlog/zf\"\n\t\"github.com/oauth2-proxy/mockoidc\"\n\t\"github.com/rs/zerolog/log\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar (\n\terrMockOidcClientIDNotDefined     = errors.New(\"MOCKOIDC_CLIENT_ID not defined\")\n\terrMockOidcClientSecretNotDefined = errors.New(\"MOCKOIDC_CLIENT_SECRET not defined\")\n\terrMockOidcPortNotDefined         = errors.New(\"MOCKOIDC_PORT not defined\")\n\terrMockOidcUsersNotDefined        = errors.New(\"MOCKOIDC_USERS not defined\")\n)\n\nconst refreshTTL = 60 * time.Minute\n\nvar accessTTL = 2 * time.Minute\n\nfunc init() {\n\trootCmd.AddCommand(mockOidcCmd)\n}\n\nvar mockOidcCmd = &cobra.Command{\n\tUse:   \"mockoidc\",\n\tShort: \"Runs a mock OIDC server for testing\",\n\tLong:  \"This internal command runs a OpenID Connect for testing purposes\",\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\terr := mockOIDC()\n\t\tif err != nil {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/headscale/cli/mockoidc.go#L5-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (old client rejected with 400 unsupported client version)\n$ tailscale version   # e.g. 1.32.0\n\n# after\n# Debian/Ubuntu example:\nsudo apt update && sudo apt install tailscale\n# or upstream:\ncurl -fsSL https://tailscale.com/install.sh | sh\ntailscale up --login-server https://headscale.example.com","handlingStrategy":"validation","validationCode":"// Check client capver before registering (mirrors isSupportedVersion).\nclientVer := tailcfg.CurrentCapabilityVersion\nif clientVer < capver.MinSupportedCapabilityVersion {\n    return fmt.Errorf(\"client capver %d too old; need >= %d (%s)\",\n        clientVer, capver.MinSupportedCapabilityVersion,\n        capver.TailscaleVersion(capver.MinSupportedCapabilityVersion))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["versioning","noise","client-compatibility","registration"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}