argoproj/argo-workflows · error
failed to create HTTP client: %w
Error message
failed to create HTTP client: %w
What it means
newSso builds a custom HTTP client (used for OIDC discovery and token exchange) from the InsecureSkipVerify and RootCA config via createHTTPClient. If that helper fails — typically because the configured RootCA cannot be parsed or read — construction is aborted and the underlying cause is wrapped with this message.
Source
Thrown at server/auth/sso/sso.go:146
if c.ClientID.Name == "" || c.ClientID.Key == "" {
return nil, fmt.Errorf("clientID empty")
}
if c.ClientSecret.Name == "" || c.ClientSecret.Key == "" {
return nil, fmt.Errorf("clientSecret empty")
}
clientSecretObj, err := secretsIf.Get(ctx, c.ClientSecret.Name, metav1.GetOptions{})
if err != nil {
return nil, err
}
// Create http client
httpClientConfig := HTTPClientConfig{
InsecureSkipVerify: c.InsecureSkipVerify,
RootCA: c.RootCA,
}
httpClient, err := createHTTPClient(httpClientConfig)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP client: %w", err)
}
oidcContext := oidc.ClientContext(ctx, httpClient)
// Some offspec providers like Azure, Oracle IDCS have oidc discovery url different from issuer url which causes issuerValidation to fail
// This providerCtx will allow the Verifier to succeed if the alternate/alias URL is in the config
if c.IssuerAlias != "" {
oidcContext = oidc.InsecureIssuerURLContext(oidcContext, c.IssuerAlias)
}
provider, err := factory(oidcContext, c.Issuer)
if err != nil {
return nil, err
}
// Claims is implemented by oidc.Provider and contains the discovery
// metadata, including the optional end_session_endpoint.
var providerMetadata struct {
EndSessionEndpoint string `json:"end_session_endpoint"`
}View on GitHub (pinned to 35bff19146)
Solutions
- Read the wrapped %w cause to identify the actual failure (bad PEM vs unreadable resource)
- Verify sso.rootCA.secretName.keySelector or rootCA.configMapName.key points to a valid PEM-encoded CA cert and that the object exists
- Grant argo-server RBAC read access to the referenced secret/configmap
- As a diagnostic only, test with the same setup but InsecureSkipVerify enabled, then fix the CA chain properly
Example fix
# before
sso:
rootCA:
configMapName: argo-root-ca
key: ca.crt # key does not exist in the configmap
# after
sso:
rootCA:
configMapName: argo-root-ca
key: root-ca.pem # valid PEM bundle present in the configmap Defensive patterns
Strategy: validation
Validate before calling
if cfg.RootCA != nil {
var caPEM []byte
// fetch from configmap/secret
if ok := x509.NewCertPool().AppendCertsFromPEM(caPEM); !ok {
return fmt.Errorf("rootCA is not a valid PEM certificate bundle")
}
} Try / catch
if _, err := sso.New(ctx, cfg, secretsIf, baseHRef, secure); err != nil {
var pe *tls.CertificateVerificationError
if errors.As(err, &pe) || strings.Contains(err.Error(), "failed to create HTTP client") {
return fmt.Errorf("check sso.rootCA reference and PEM validity: %w", err)
}
return err
} Prevention
- Verify the configmap/secret key holding the CA is valid PEM before rollout
- Confirm argo-server RBAC can read the rootCA source object
- Keep the issuer's full chain in the bundle (leaf + intermediates)
When it happens
Trigger: Calling New with sso.rootCA.secretName/rootCA.configMapName pointing at a missing, unreadable, or malformed CA bundle, so tls.X509KeyPool/AppendCertsFromPEM fails inside createHTTPClient.
Common situations: Typo or wrong key in the rootCA configmap/secret reference; CA bundle stored as non-PEM data; RBAC preventing argo-server from reading the referenced configmap/secret (often surfaced as the wrapped error).
Related errors
- request failed with: %w
- failed to load system cert pool: %w
- failed to append certificates from PEM string
- clientSecret empty
- key %s missing in secret %s
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/8c4232db3e84ec4c.
Report an issue: GitHub.