fatedier/frp · error
cannot specify both auth.oidc.tokenSource and any other fiel
Error message
cannot specify both auth.oidc.tokenSource and any other field of auth.oidc
What it means
When auth.oidc.tokenSource is configured, it must be the ONLY field under auth.oidc. The validator rejects any config that sets tokenSource alongside clientID, clientSecret, audience, scope, tokenEndpointURL, additionalEndpointParams, trustedCaFile, insecureSkipVerify, or proxyURL, because the token then comes entirely from the external source.
Source
Thrown at pkg/config/v1/validation/client.go:130
}
if c.Method == v1.AuthMethodOIDC && c.OIDC.TokenSource == nil {
if err := ValidateOIDCClientCredentialsConfig(&c.OIDC); err != nil {
errs = AppendError(errs, err)
}
}
return nil, errs
}
func (v *ConfigValidator) validateOIDCConfig(c *v1.AuthOIDCClientConfig) error {
if c.TokenSource == nil {
return nil
}
var errs error
// Validate oidc.tokenSource mutual exclusivity with other fields of oidc
if c.ClientID != "" || c.ClientSecret != "" || c.Audience != "" ||
c.Scope != "" || c.TokenEndpointURL != "" || len(c.AdditionalEndpointParams) > 0 ||
c.TrustedCaFile != "" || c.InsecureSkipVerify || c.ProxyURL != "" {
errs = AppendError(errs, fmt.Errorf("cannot specify both auth.oidc.tokenSource and any other field of auth.oidc"))
}
if c.TokenSource.Type == "exec" {
if err := v.ValidateUnsafeFeature(security.TokenSourceExec); err != nil {
errs = AppendError(errs, err)
}
}
if err := c.TokenSource.Validate(); err != nil {
errs = AppendError(errs, fmt.Errorf("invalid auth.oidc.tokenSource: %v", err))
}
return errs
}
func validateTransportConfig(c *v1.ClientTransportConfig) (Warning, error) {
var (
warnings Warning
errs error
)
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Delete all other auth.oidc fields (clientID, clientSecret, audience, scope, tokenEndpointURL, additionalEndpointParams, trustedCaFile, insecureSkipVerify, proxyURL) leaving only tokenSource
- Or drop tokenSource and use full static OIDC credentials instead
- Re-run frpc verify (frpc verify -c frpc.toml) after editing to confirm the exclusivity check passes
Example fix
# before [auth] method = "oidc" [auth.oidc] clientID = "my-client" audience = "frp" [auth.oidc.tokenSource] type = "exec" command = "oidc-token-helper" # after [auth] method = "oidc" [auth.oidc] [auth.oidc.tokenSource] type = "exec" command = "oidc-token-helper"
Defensive patterns
Strategy: validation
Validate before calling
func oidcExclusive(c *v1.AuthOIDCClientConfig) bool {
if c.TokenSource == nil {
return true
}
return c.ClientID == "" && c.ClientSecret == "" && c.Audience == "" &&
c.Scope == "" && c.TokenEndpointURL == "" &&
len(c.AdditionalEndpointParams) == 0 && c.TrustedCaFile == "" &&
!c.InsecureSkipVerify && c.ProxyURL == ""
} Try / catch
if _, err := validation.ValidateClientCommonConfig(cfg); err != nil {
if strings.Contains(err.Error(), "cannot specify both auth.oidc.tokenSource") {
cfg.Auth.OIDC = v1.AuthOIDCClientConfig{TokenSource: cfg.Auth.OIDC.TokenSource}
}
} Prevention
- When adopting tokenSource, zero out the whole oidc block first
- Keep one canonical OIDC config per auth mode in your config management
When it happens
Trigger: Setting auth.oidc.tokenSource.* while leaving any static OIDC credential field populated, e.g. keeping clientID/clientSecret from a previously working static config after adding a tokenSource exec plugin.
Common situations: Gradually migrating from static OIDC client credentials to an exec-based token source and forgetting to delete the old fields; merging config snippets; defaults injected by a template tool that fill audience or scope automatically.
Related errors
- exec configuration is required when type is 'exec'
- file path cannot be empty
- cannot specify both auth.token and auth.tokenSource
- invalid auth.tokenSource: %v
- invalid auth method, optional values are %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/91f73a8117339353.
Report an issue: GitHub.