fatedier/frp · error
failed to read OIDC CA certificate file %q: %w
Error message
failed to read OIDC CA certificate file %q: %w
What it means
The OIDC auth setup tried to load the configured trusted CA file (oidc.trustedCAFile) with os.ReadFile and the read failed. The path is used verbatim, so this is a classic file-access failure wrapped with the offending path in the message.
Source
Thrown at pkg/auth/oidc.go:51
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/msg"
)
// createOIDCHTTPClient creates an HTTP client with custom TLS and proxy configuration for OIDC token requests
func createOIDCHTTPClient(trustedCAFile string, insecureSkipVerify bool, proxyURL string) (*http.Client, error) {
// Clone the default transport to get all reasonable defaults
transport := http.DefaultTransport.(*http.Transport).Clone()
// Configure TLS settings
if trustedCAFile != "" || insecureSkipVerify {
tlsConfig := &tls.Config{
InsecureSkipVerify: insecureSkipVerify,
}
if trustedCAFile != "" && !insecureSkipVerify {
caCert, err := os.ReadFile(trustedCAFile)
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)
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Check the exact path in the error message with ls -l as the service user; fix existence and read permission.
- Use an absolute path for oidc.trustedCAFile to avoid working-directory ambiguity.
- In containers, mount the CA file at the configured path.
- If the OIDC provider uses a public CA, remove oidc.trustedCAFile and rely on system roots.
Example fix
# before (frps.toml) [auth] method = "oidc" [auth.oidc] trustedCAFile = "ca.pem" # relative, not next to binary # after [auth] method = "oidc" [auth.oidc] trustedCAFile = "/etc/frp/oidc-ca.pem"
Defensive patterns
Strategy: validation
Validate before calling
if cfg.Auth.OIDC.TrustedCAFile != "" {
if _, err := os.Stat(cfg.Auth.OIDC.TrustedCAFile); err != nil {
return fmt.Errorf("OIDC CA file missing or unreadable: %w", err)
}
} Prevention
- Use absolute paths for oidc.trustedCAFile
- Mount CA files into containers at fixed paths
- Pre-flight file readability as the service user before start
When it happens
Trigger: oidc.trustedCAFile set to a path that doesn't exist, is a directory, or is unreadable by the process user; relative paths are resolved against the process working directory rather than the config location.
Common situations: CA file not shipped to the host or placed at a different path than configured; running in a container without mounting the CA; root-owned file with the service running as non-root; typo in the path.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to parse OIDC CA certificate from file %q
- auth.oidc.clientID is required; auth.oidc.tokenEndpointURL i
- failed to create OIDC HTTP client: %w
- cannot specify both auth.oidc.tokenSource and any other fiel
- exec configuration is required when type is 'exec'
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/b993d20a48dc1f5e.
Report an issue: GitHub.