fatedier/frp · error
failed to parse OIDC proxy URL %q: %w
Error message
failed to parse OIDC proxy URL %q: %w
What it means
frpc's OIDC authentication builds a dedicated HTTP client for the token endpoint. When oidc.proxyURL is set, that string is passed to Go's url.Parse; if parsing fails the client construction aborts with this wrapped error. url.Parse only rejects structurally invalid URLs (e.g. control characters, missing scheme like 'host:8080' being misread), so in practice the configured value is malformed rather than merely unreachable.
Source
Thrown at pkg/auth/oidc.go:68
if err != nil {
return nil, fmt.Errorf("failed to read OIDC CA certificate file %q: %w", trustedCAFile, err)
}
caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM(caCert) {
return nil, fmt.Errorf("failed to parse OIDC CA certificate from file %q", trustedCAFile)
}
tlsConfig.RootCAs = caCertPool
}
transport.TLSClientConfig = tlsConfig
}
// Configure proxy settings
if proxyURL != "" {
parsedURL, err := url.Parse(proxyURL)
if err != nil {
return nil, fmt.Errorf("failed to parse OIDC proxy URL %q: %w", proxyURL, err)
}
transport.Proxy = http.ProxyURL(parsedURL)
} else {
// Explicitly disable proxy to override DefaultTransport's ProxyFromEnvironment
transport.Proxy = nil
}
return &http.Client{Transport: transport}, nil
}
// nonCachingTokenSource wraps a clientcredentials.Config to fetch a fresh
// token on every call. This is used as a fallback when the OIDC provider
// does not return expires_in, which would cause a caching TokenSource to
// hold onto a stale token forever.
type nonCachingTokenSource struct {
cfg *clientcredentials.Config
ctx context.Context
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Correct the proxy URL to a fully qualified form with scheme and host, e.g. http://proxy.example.com:8080 or socks5://127.0.0.1:1080
- Verify scheme spelled exactly http, https, or socks5 followed by '://'
- Remove any surrounding quotes, spaces, or stray characters from the config value
- Test the value in isolation: url.Parse("socks5://127.0.0.1:1080") must succeed
Example fix
// frpc.toml before authentication.method = "oidc" authentication.oidc.proxyURL = "127.0.0.1:8080" // after authentication.method = "oidc" authentication.oidc.proxyURL = "http://127.0.0.1:8080"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(proxyURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("oidc.proxyURL must be a full URL like http://host:port, got %q", proxyURL)
} Try / catch
if err := validateProxyURL(cfg.ProxyURL); err != nil { return err } // fail fast before NewOidcAuthProvider Prevention
- Always write proxy URLs with an explicit scheme (http:// or socks5://)
- Validate the URL with url.Parse and a non-empty Host check in config-validation tooling
- Keep proxy addresses in one config variable instead of duplicating them
When it happens
Trigger: Client config with authentication.oidc enabled and oidc.proxyURL set to a value Go cannot parse: 'socks5 :1080' (space instead of ://), '127.0.0.1:8080' (parsed as scheme '127.0.0.1'), a URL containing spaces or control characters, or a scheme with invalid characters.
Common situations: Routing frpc's OIDC token fetch through a corporate proxy; users write a bare host:port without the http:// scheme, or copy a proxy address with a typo; recently migrating from env-var HTTP_PROXY to the explicit oidc.proxyURL field.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse proxy %s, err: %v
- unknown proxy type: %s
- unmarshal ProxyConfig error: %v
- decode proxy at index %d: %w
- cannot specify both auth.oidc.tokenSource and any other fiel
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/a2bb99381940fd66.
Report an issue: GitHub.