t8y2/dbx · error

failed to parse CA certificate at %s

Error message

failed to parse CA certificate at %s

What it means

tlsConfigFor reads the configured CA certificate PEM file and appends it to an x509 CertPool; AppendCertsFromPEM returns false when the file contains no parseable certificates, and the agent converts that into this error naming the file path. The TLS connection is aborted before any request is sent.

Source

Thrown at agents/drivers/etcd2-go/client.go:185

	if seconds < 1 {
		seconds = 1
	}
	if seconds > 300 {
		seconds = 300
	}
	return time.Duration(seconds) * time.Second
}

func tlsConfigFor(connection connectionParams) (*tls.Config, error) {
	tlsConfig := &tls.Config{}
	if ca := strings.TrimSpace(connection.CACertPath); ca != "" {
		authorityPEM, err := os.ReadFile(ca)
		if err != nil {
			return nil, err
		}
		pool := x509.NewCertPool()
		if !pool.AppendCertsFromPEM(authorityPEM) {
			return nil, fmt.Errorf("failed to parse CA certificate at %s", ca)
		}
		tlsConfig.RootCAs = pool
	}
	certPath := firstNonBlank(connection.ClientCertPath, connection.CertPath)
	keyPath := firstNonBlank(connection.ClientKeyPath, connection.KeyPath)
	if (certPath == "") != (keyPath == "") {
		return nil, errors.New("Client certificate and key must be provided together")
	}
	if certPath != "" {
		pair, err := tls.LoadX509KeyPair(certPath, keyPath)
		if err != nil {
			return nil, err
		}
		tlsConfig.Certificates = []tls.Certificate{pair}
	}
	return tlsConfig, nil
}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Verify the file at the path is a PEM-encoded certificate (begins with '-----BEGIN CERTIFICATE-----')
  2. Regenerate or re-export the CA cert in PEM format (e.g. openssl x509 -in ca.der -out ca.pem -outform PEM)
  3. Check the path/config — ensure cacert points to the CA, not the client cert/key, and that the secret mounted correctly

Example fix

// before
config := map[string]any{"endpoints": ["https://e:2379"], "cacert": "/etc/pki/ca.der"}

// after
// convert to PEM first: openssl x509 -inform DER -in ca.der -out ca.pem
config := map[string]any{"endpoints": ["https://e:2379"], "cacert": "/etc/pki/ca.pem"}
Defensive patterns

Strategy: validation

Validate before calling

func validateCAPEM(path string) error {
    pem, err := os.ReadFile(path)
    if err != nil { return err }
    if !strings.Contains(string(pem), "-----BEGIN CERTIFICATE-----") {
        return fmt.Errorf("%s is not a PEM certificate", path)
    }
    pool := x509.NewCertPool()
    if !pool.AppendCertsFromPEM(pem) { return fmt.Errorf("%s has no parseable certs", path) }
    return nil
}

Try / catch

cfg, err := buildTLSConfig(caPath, certPath, keyPath)
if err != nil && strings.Contains(err.Error(), "failed to parse CA certificate") {
    return fmt.Errorf("check cacert %s: must be PEM x509 cert, got invalid file", caPath)
}

Prevention

When it happens

Trigger: Configuring a connection whose CA path points to a file that does not contain any valid PEM certificate blocks (wrong file, empty file, DER-encoded cert, concatenated junk).

Common situations: Pointing cacert at a private key or CSR instead of a certificate; a DER (.crt binary) cert that Go cannot parse as PEM; an empty or truncated file from a failed secret mount; copying the wrong file in Kubernetes secret volumes.

Understand the failure class

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/6339bcd27f3bbc96. Report an issue: GitHub.