fatedier/frp · error
failed to parse OIDC CA certificate from file %q
Error message
failed to parse OIDC CA certificate from file %q
What it means
The OIDC trusted CA file was read successfully but x509.NewCertPool().AppendCertsFromPEM rejected its contents: no PEM-encoded certificate blocks could be parsed from the bytes. This validates content, not access; the file exists but is not a usable CA bundle.
Source
Thrown at pkg/auth/oidc.go:56
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)
}
transport.Proxy = http.ProxyURL(parsedURL)
} else {
// Explicitly disable proxy to override DefaultTransport's ProxyFromEnvironment
transport.Proxy = nil
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Inspect the file: it must contain '-----BEGIN CERTIFICATE-----' blocks; re-export the CA in PEM.
- If you have DER, convert it: openssl x509 -inform der -in ca.der -out ca.pem.
- Validate before starting frps: openssl x509 -in ca.pem -noout must succeed for each block.
- Ensure the file holds the CA or full chain, not just the server key.
Example fix
# verify/convert before starting frps openssl x509 -in /etc/frp/oidc-ca.pem -noout || \ openssl x509 -inform der -in /etc/frp/oidc-ca.der -out /etc/frp/oidc-ca.pem
Defensive patterns
Strategy: validation
Validate before calling
pemBytes, err := os.ReadFile(cfg.Auth.OIDC.TrustedCAFile)
if err == nil && !x509.NewCertPool().AppendCertsFromPEM(pemBytes) {
return fmt.Errorf("OIDC CA file is not valid PEM: %s", cfg.Auth.OIDC.TrustedCAFile)
} Type guard
func isPEMCertificateFile(path string) bool {
b, err := os.ReadFile(path)
if err != nil {
return false
}
return x509.NewCertPool().AppendCertsFromPEM(b)
} Prevention
- Distribute CA files via config management, never copy/paste
- Validate with `openssl x509 -in file -noout` in CI
- Convert DER to PEM explicitly when receiving certs from vendors
When it happens
Trigger: oidc.trustedCAFile contains only a private key or leaf cert, a DER (binary) certificate, stray text around the PEM blocks, or was truncated or copied with formatting damage.
Common situations: Pointing trustedCAFile at a TLS key file instead of the CA cert; DER certificate not converted to PEM; copy/paste artifacts (missing BEGIN/END lines, CRLF, escaped newlines); empty file.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- auth.oidc.clientID is required; auth.oidc.tokenEndpointURL i
- failed to read OIDC CA certificate file %q: %w
- cannot specify both auth.oidc.tokenSource and any other fiel
- exec configuration is required when type is 'exec'
- file path cannot be empty
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/8d0abc3152eb37f1.
Report an issue: GitHub.