grafana/k6 · error
failed to append root certificate to the pool
Error message
failed to append root certificate to the pool
What it means
Thrown while building TLS config for the OpenTelemetry output when the PEM file at K6_OTEL_TLS_CERTIFICATE exists and was read successfully, but x509.CertPool.AppendCertsFromPEM returned false, meaning the bytes contained no parseable PEM certificate block. This guards against corrupt or misformatted CA bundles before the exporter connects.
Source
Thrown at internal/output/opentelemetry/tls.go:36
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS13,
}
if insecureSkipVerify.Valid {
tlsConfig.InsecureSkipVerify = insecureSkipVerify.Bool
set = true
}
// Load the root certificate
if certPath.Valid {
b, err := os.ReadFile(certPath.String) //nolint:forbidigo
if err != nil {
return nil, fmt.Errorf("failed to read root certificate from %q: %w", certPath.String, err)
}
cp := x509.NewCertPool()
if ok := cp.AppendCertsFromPEM(b); !ok {
return nil, errors.New("failed to append root certificate to the pool")
}
tlsConfig.RootCAs = cp
set = true
}
// Load the client certificate
if clientCertPath.Valid {
cert, err := tls.LoadX509KeyPair(clientCertPath.String, clientKeyPath.String)
if err != nil {
return nil, fmt.Errorf("failed to load client certificate: %w", err)
}
tlsConfig.Certificates = []tls.Certificate{cert}
set = true
}
if !set {View on GitHub (pinned to 93accf6570)
Solutions
- Verify the file is PEM: it must contain '-----BEGIN CERTIFICATE-----' blocks; openssl x509 -in ca.pem -text -noout should succeed
- Convert DER to PEM: openssl x509 -inform der -in ca.der -out ca.pem
- Check you passed the CA bundle path, not the client cert/key (use K6_OTEL_TLS_CLIENT_CERTIFICATE + K6_OTEL_TLS_CLIENT_KEY for mTLS)
- Re-export the certificate from the source of truth to repair truncation or CRLF damage
Example fix
# before # ca.der is binary DER -> AppendCertsFromPEM fails export K6_OTEL_TLS_CERTIFICATE=/certs/ca.der # after openssl x509 -inform der -in /certs/ca.der -out /certs/ca.pem export K6_OTEL_TLS_CERTIFICATE=/certs/ca.pem
Defensive patterns
Strategy: validation
Validate before calling
# Fail fast on non-PEM CA bundles before running k6:
CA=${K6_OTEL_TLS_CERTIFICATE:?}
openssl x509 -in "$CA" -noout 2>/dev/null || { echo "$CA is not valid PEM"; exit 1; } Prevention
- Validate certificates in your provisioning pipeline with openssl before injecting them
- Keep PEM files untouched by templating systems (no variable substitution inside cert files)
- Distinct paths for root CA vs client cert/key; verify with a checklist when configuring mTLS
When it happens
Trigger: Pointing K6_OTEL_TLS_CERTIFICATE at a DER-encoded (binary) CA file instead of PEM; a certificate file that was truncated, mangled by templating, or contains only a private key/certificate chain header without CERTIFICATE blocks; accidentally passing the client key path in the CA field; line-ending corruption (CRLF injection) from Windows tooling.
Common situations: Ops teams exporting certs from vaults that re-encode formats; copy-paste errors that drop BEGIN/END lines; mixing up K6_OTEL_TLS_CERTIFICATE (root CA) with K6_OTEL_TLS_CLIENT_CERTIFICATE (mutual TLS pair).
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to append ca certificate [%d] from PEM
- failed to decode PEM key
- failed to append certificate from PEM: %w
- unsupported public key algorithm
- encrypted pkcs8 formatted key is not supported
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/76979d8cd93801dc.
Report an issue: GitHub.