{"record":{"id":"b993d20a48dc1f5e","repo":"fatedier/frp","slug":"failed-to-read-oidc-ca-certificate-file-q-w","errorCode":null,"errorMessage":"failed to read OIDC CA certificate file %q: %w","messagePattern":"failed to read OIDC CA certificate file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/oidc.go","lineNumber":51,"sourceCode":"\t\"github.com/fatedier/frp/pkg/config/v1/validation\"\n\t\"github.com/fatedier/frp/pkg/msg\"\n)\n\n// createOIDCHTTPClient creates an HTTP client with custom TLS and proxy configuration for OIDC token requests\nfunc createOIDCHTTPClient(trustedCAFile string, insecureSkipVerify bool, proxyURL string) (*http.Client, error) {\n\t// Clone the default transport to get all reasonable defaults\n\ttransport := http.DefaultTransport.(*http.Transport).Clone()\n\n\t// Configure TLS settings\n\tif trustedCAFile != \"\" || insecureSkipVerify {\n\t\ttlsConfig := &tls.Config{\n\t\t\tInsecureSkipVerify: insecureSkipVerify,\n\t\t}\n\n\t\tif trustedCAFile != \"\" && !insecureSkipVerify {\n\t\t\tcaCert, err := os.ReadFile(trustedCAFile)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to read OIDC CA certificate file %q: %w\", trustedCAFile, err)\n\t\t\t}\n\n\t\t\tcaCertPool := x509.NewCertPool()\n\t\t\tif !caCertPool.AppendCertsFromPEM(caCert) {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to parse OIDC CA certificate from file %q\", trustedCAFile)\n\t\t\t}\n\n\t\t\ttlsConfig.RootCAs = caCertPool\n\t\t}\n\t\ttransport.TLSClientConfig = tlsConfig\n\t}\n\n\t// Configure proxy settings\n\tif proxyURL != \"\" {\n\t\tparsedURL, err := url.Parse(proxyURL)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse OIDC proxy URL %q: %w\", proxyURL, err)\n\t\t}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/auth/oidc.go#L33-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (frps.toml)\n[auth]\nmethod = \"oidc\"\n[auth.oidc]\ntrustedCAFile = \"ca.pem\"   # relative, not next to binary\n\n# after\n[auth]\nmethod = \"oidc\"\n[auth.oidc]\ntrustedCAFile = \"/etc/frp/oidc-ca.pem\"","handlingStrategy":"validation","validationCode":"if cfg.Auth.OIDC.TrustedCAFile != \"\" {\n    if _, err := os.Stat(cfg.Auth.OIDC.TrustedCAFile); err != nil {\n        return fmt.Errorf(\"OIDC CA file missing or unreadable: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for oidc.trustedCAFile","Mount CA files into containers at fixed paths","Pre-flight file readability as the service user before start"],"tags":["auth","oidc","tls","filesystem"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}