{"record":{"id":"d03612db8d6afdb0","repo":"fatedier/frp","slug":"failed-to-create-oidc-http-client-w","errorCode":null,"errorMessage":"failed to create OIDC HTTP client: %w","messagePattern":"failed to create OIDC HTTP client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/oidc.go","lineNumber":161,"sourceCode":"\t\teps[\"audience\"] = []string{cfg.Audience}\n\t}\n\n\ttokenGenerator := &clientcredentials.Config{\n\t\tClientID:       cfg.ClientID,\n\t\tClientSecret:   cfg.ClientSecret,\n\t\tScopes:         []string{cfg.Scope},\n\t\tTokenURL:       cfg.TokenEndpointURL,\n\t\tEndpointParams: eps,\n\t}\n\n\t// Build the context that TokenSource will use for all future HTTP requests.\n\t// context.Background() is appropriate here because the token source is\n\t// long-lived and outlives any single request.\n\tctx := context.Background()\n\tif cfg.TrustedCaFile != \"\" || cfg.InsecureSkipVerify || cfg.ProxyURL != \"\" {\n\t\thttpClient, err := createOIDCHTTPClient(cfg.TrustedCaFile, cfg.InsecureSkipVerify, cfg.ProxyURL)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create OIDC HTTP client: %w\", err)\n\t\t}\n\t\tctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)\n\t}\n\n\t// Create a persistent TokenSource that caches the token and refreshes\n\t// it before expiry. This avoids making a new HTTP request to the OIDC\n\t// provider on every heartbeat/ping.\n\t//\n\t// We wrap it in an oidcTokenSource so that the first Token() call\n\t// (deferred to SetLogin inside the login retry loop) probes whether the\n\t// provider returns expires_in.  If not, it switches to a non-caching\n\t// source.  This avoids an eager network call at construction time, which\n\t// would prevent loopLoginUntilSuccess from retrying on transient IdP\n\t// outages.\n\tcachingSource := tokenGenerator.TokenSource(ctx)\n\n\treturn &OidcAuthProvider{\n\t\tadditionalAuthScopes: additionalAuthScopes,","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/auth/oidc.go#L143-L179","documentation":"When any of oidc.trustedCaFile, oidc.insecureSkipVerify, or oidc.proxyURL is configured, frpc calls createOIDCHTTPClient to build an http.Client with the custom TLS/proxy settings. This error wraps any failure inside that constructor: reading or parsing the CA certificate file, or parsing the proxy URL. It is raised at auth-provider construction time (NewOidcAuthProvider), before any connection to frps is attempted.","triggerScenarios":"Calling NewOidcAuthProvider with cfg.TrustedCaFile pointing to a nonexistent or unreadable file, a file that is not valid PEM ('failed to parse OIDC CA certificate from file'), or a ProxyURL that url.Parse rejects (see error 140).","commonSituations":"Mounting a corporate root CA into a container at the wrong path; the CA file is a DER-encoded or otherwise non-PEM bundle; file permissions deny the frpc process; typo in the proxy URL configured at the same time.","solutions":["Check the wrapped error text: it names whether the CA file or the proxy URL is at fault","For CA issues, verify the path exists and contains a valid PEM block: openssl x509 -in ca.pem -noout","Convert DER to PEM if needed: openssl x509 -inform der -in ca.crt -out ca.pem, then point trustedCaFile at ca.pem","For proxy issues, fix the URL as described for 'failed to parse OIDC proxy URL'","Ensure the frpc process has read permission on the CA file (check ownership in containers)"],"exampleFix":"# before: file not readable / wrong format\nauthentication.oidc.trustedCaFile = \"/etc/ca/root.crt\"   # DER-encoded\n\n# after\nopenssl x509 -inform der -in /etc/ca/root.crt -out /etc/frp/ca.pem\nauthentication.oidc.trustedCaFile = \"/etc/frp/ca.pem\"","handlingStrategy":"validation","validationCode":"if cfg.TrustedCaFile != \"\" {\n    pem, err := os.ReadFile(cfg.TrustedCaFile)\n    if err != nil { return err }\n    if !bytes.Contains(pem, []byte(\"-----BEGIN CERTIFICATE-----\")) {\n        return fmt.Errorf(\"%s is not PEM-encoded\", cfg.TrustedCaFile)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run openssl x509 -in <cafile> -noout in deployment scripts before starting frp","Mount CA files read-only at fixed paths in containers","Validate the proxy URL up front (see error 140)"],"tags":["frp","oidc","tls","ca-certificate","http-client"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}