argoproj/argo-workflows · error
failed to parse certificate authority %q
Error message
failed to parse certificate authority %q
What it means
The CA file at caCert was read successfully, but its contents are not a valid PEM-encoded certificate, so AppendCertsFromPEM added nothing to the root pool. GetClientTLSConfig rejects the config rather than silently trusting no roots.
Source
Thrown at util/tls/tls.go:173
// Client certificate authentication requires both clientCert and clientKey. If caCert is provided,
// the certificate authority is used instead of the system roots to verify the server certificate.
// The insecureSkipVerify parameter controls whether the server's certificate is verified.
func GetClientTLSConfig(clientCert, clientKey, caCert string, insecureSkipVerify bool) (*tls.Config, error) {
tlsConfig := &tls.Config{
InsecureSkipVerify: insecureSkipVerify,
MinVersion: tls.VersionTLS12,
}
if (clientCert == "") != (clientKey == "") {
return nil, fmt.Errorf("client certificate authentication requires both clientCert and clientKey")
}
if caCert != "" {
caPEM, err := os.ReadFile(caCert)
if err != nil {
return nil, fmt.Errorf("failed to read certificate authority: %w", err)
}
certPool := x509.NewCertPool()
if ok := certPool.AppendCertsFromPEM(caPEM); !ok {
return nil, fmt.Errorf("failed to parse certificate authority %q", caCert)
}
tlsConfig.RootCAs = certPool
}
if clientCert != "" && clientKey != "" {
cert, err := tls.LoadX509KeyPair(clientCert, clientKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
}
return tlsConfig, nil
}
View on GitHub (pinned to 35bff19146)
Solutions
- Inspect the file: it must contain a '-----BEGIN CERTIFICATE-----' PEM block (openssl x509 -in ca.crt -text -noout)
- Re-download/export the CA in PEM format (for DER: openssl x509 -inform der -in ca.der -out ca.crt)
- Make sure the path points to the CA certificate, not the key or a stale error-page file
- Regenerate or re-fetch the Argo server CA from the correct secret/configmap
Example fix
# before (DER binary fails to parse) ca.der # after openssl x509 -inform der -in ca.der -out ca.crt # then pass ca.crt as the caCert argument
Defensive patterns
Strategy: validation
Validate before calling
func validCAPEM(path string) error {
b, err := os.ReadFile(path)
if err != nil { return err }
if !bytes.Contains(b, []byte("-----BEGIN CERTIFICATE-----")) {
return fmt.Errorf("%s is not PEM certificate data", path)
}
pool := x509.NewCertPool()
if !pool.AppendCertsFromPEM(b) { return fmt.Errorf("%s: no parseable certs", path) }
return nil
} Try / catch
if err := validCAPEM(caCert); err != nil {
return fmt.Errorf("invalid CA bundle: %w", err)
}
config, err := tls.GetClientTLSConfig(clientCert, clientKey, caCert, insecure) Prevention
- Validate downloaded CA files contain BEGIN CERTIFICATE PEM blocks
- Don't save HTML error pages from proxied downloads as cert files
- Convert DER certs to PEM before use (openssl x509 -inform der)
- Keep CA bundles and keys in clearly named separate files
When it happens
Trigger: Calling GetClientTLSConfig with a caCert path whose file contains empty data, HTML (e.g. a proxy error page), a private key instead of a cert, a DER-encoded binary cert, or an otherwise malformed PEM block.
Common situations: Downloading the CA with curl through an auth-walled proxy and saving the HTML error page; pointing at the client key instead of the CA cert; using a DER/binary certificate without converting to PEM; truncated or concatenated wrong files.
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
- failed to append certificates from PEM string
- failed to read certificate authority: %w
- --client-certificate and --client-key must be provided toget
- failed to parse ClusterWorkflowTemplate: %w
- failed to parse unknown kind %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/d2cd62164236de2a.
Report an issue: GitHub.