{"record":{"id":"77512ba03da1c805","repo":"juanfont/headscale","slug":"oidc-client-secret-or-oidc-client-secret-path-is-r","errorCode":null,"errorMessage":"oidc.client_secret or oidc.client_secret_path is required when oidc.issuer is set","messagePattern":"oidc\\.client_secret or oidc\\.client_secret_path is required when oidc\\.issuer is set","errorType":"validation","errorClass":"errOIDCClientSecretRequired","httpStatus":null,"severity":"error","filePath":"hscontrol/types/config.go","lineNumber":38,"sourceCode":"\t\"go4.org/netipx\"\n\t\"tailscale.com/net/tsaddr\"\n\t\"tailscale.com/tailcfg\"\n\t\"tailscale.com/types/dnstype\"\n\t\"tailscale.com/util/set\"\n)\n\nconst (\n\tPKCEMethodPlain string = \"plain\"\n\tPKCEMethodS256  string = \"S256\"\n\n\tdefaultNodeStoreBatchSize = 100\n)\n\nvar (\n\terrOidcMutuallyExclusive     = errors.New(\"oidc_client_secret and oidc_client_secret_path are mutually exclusive\")\n\terrOIDCIssuerInvalid         = errors.New(\"oidc.issuer must be a valid http(s) URL\")\n\terrOIDCClientIDRequired      = errors.New(\"oidc.client_id is required when oidc.issuer is set\")\n\terrOIDCClientSecretRequired  = errors.New(\"oidc.client_secret or oidc.client_secret_path is required when oidc.issuer is set\")\n\terrServerURLSuffix           = errors.New(\"server_url cannot be part of base_domain in a way that could make the DERP and headscale server unreachable\")\n\terrServerURLSame             = errors.New(\"server_url cannot use the same domain as base_domain in a way that could make the DERP and headscale server unreachable\")\n\terrInvalidPKCEMethod         = errors.New(\"pkce.method must be either 'plain' or 'S256'\")\n\terrTrustedProxyZeroRange     = errors.New(\"0.0.0.0/0 and ::/0 are not allowed\")\n\tErrNoPrefixConfigured        = errors.New(\"no IPv4 or IPv6 prefix configured, minimum one prefix is required\")\n\tErrInvalidAllocationStrategy = errors.New(\"invalid prefix allocation strategy\")\n)\n\ntype IPAllocationStrategy string\n\nconst (\n\tIPAllocationStrategySequential IPAllocationStrategy = \"sequential\"\n\tIPAllocationStrategyRandom     IPAllocationStrategy = \"random\"\n)\n\ntype PolicyMode string\n\nconst (","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/types/config.go#L20-L56","documentation":"errOIDCClientSecretRequired is an unexported config validation error in hscontrol/types/config.go:38 returned at config.go:392 when oidc.issuer is set but neither oidc.client_secret nor oidc.client_secret_path is provided. Exactly one secret source is mandatory; setting both trips errOidcMutuallyExclusive instead.","triggerScenarios":"Configuring oidc.issuer and client_id without any secret; setting client_secret_path to a path but the key name misspelled so viper reads it as unset; empty-string secret from templating.","commonSituations":"Incomplete first-time OIDC setups; secret paths mounted but the config key typed as client_secret_file; environment-specific overlays forgetting the secret key.","solutions":["Set oidc.client_secret to the IdP client's secret, or oidc.client_secret_path to a readable file containing it","If using client_secret_path, verify the key spelling and that the file exists and is readable by headscale","Never set both keys (see the mutually-exclusive error)","Restart headscale after the fix"],"exampleFix":"# before\noidc:\n  issuer: https://idp.example.com\n  client_id: headscale\n\n# after\noidc:\n  issuer: https://idp.example.com\n  client_id: headscale\n  client_secret_path: /run/secrets/oidc-client-secret","handlingStrategy":"validation","validationCode":"if cfg.OIDC.Issuer != \"\" && cfg.OIDC.ClientSecret == \"\" && cfg.OIDC.ClientSecretPath == \"\" {\n    return errors.New(\"client_secret or client_secret_path required\")\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Verify the secret file path is spelled client_secret_path and is readable","Use config linting to catch missing OIDC secret keys before deploy"],"tags":["headscale","config","oidc","secrets","validation"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}