{"record":{"id":"76979d8cd93801dc","repo":"grafana/k6","slug":"failed-to-append-root-certificate-to-the-pool","errorCode":null,"errorMessage":"failed to append root certificate to the pool","messagePattern":"failed to append root certificate to the pool","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/output/opentelemetry/tls.go","lineNumber":36,"sourceCode":"\ttlsConfig := &tls.Config{\n\t\tMinVersion: tls.VersionTLS13,\n\t}\n\n\tif insecureSkipVerify.Valid {\n\t\ttlsConfig.InsecureSkipVerify = insecureSkipVerify.Bool\n\t\tset = true\n\t}\n\n\t// Load the root certificate\n\tif certPath.Valid {\n\t\tb, err := os.ReadFile(certPath.String) //nolint:forbidigo\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read root certificate from %q: %w\", certPath.String, err)\n\t\t}\n\n\t\tcp := x509.NewCertPool()\n\t\tif ok := cp.AppendCertsFromPEM(b); !ok {\n\t\t\treturn nil, errors.New(\"failed to append root certificate to the pool\")\n\t\t}\n\n\t\ttlsConfig.RootCAs = cp\n\t\tset = true\n\t}\n\n\t// Load the client certificate\n\tif clientCertPath.Valid {\n\t\tcert, err := tls.LoadX509KeyPair(clientCertPath.String, clientKeyPath.String)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to load client certificate: %w\", err)\n\t\t}\n\n\t\ttlsConfig.Certificates = []tls.Certificate{cert}\n\t\tset = true\n\t}\n\n\tif !set {","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/output/opentelemetry/tls.go#L18-L54","documentation":"When K6_OTEL_TLS_CERTIFICATE points at a root CA for the OTel exporter's TLS connection, k6 reads the file and feeds it to x509.CertPool.AppendCertsFromPEM. If the file was read successfully but does not contain parseable PEM certificate blocks (e.g., it is DER-encoded binary, a malformed bundle, or not a certificate at all), the append fails and the output returns this error.","triggerScenarios":"K6_OTEL_TLS_CERTIFICATE pointing at a DER/binary .crt file (common for Windows-exported CAs); a truncated or concatenated-with-garbage PEM bundle; a proxy that saved an HTML error page as ca.pem.","commonSituations":"Corporate proxy/CA setups where the provided CA file is DER, not PEM; manual copy-paste of certs that lost the BEGIN/END lines; expired-then-regenerated bundles with stray bytes.","solutions":["Convert DER to PEM: openssl x509 -inform der -in ca.cer -out ca.pem and point K6_OTEL_TLS_CERTIFICATE at ca.pem","Verify the file first: openssl x509 -in ca.pem -noout -subject (or check it starts with '-----BEGIN CERTIFICATE-----')","Re-download/export the CA bundle from the source that issued it instead of hand-editing"],"exampleFix":"# before\nexport K6_OTEL_TLS_CERTIFICATE=/etc/certs/ca.cer   # DER-encoded\nk6 run -o opentelemetry script.js\n# after\nopenssl x509 -inform der -in /etc/certs/ca.cer -out /etc/certs/ca.pem\nexport K6_OTEL_TLS_CERTIFICATE=/etc/certs/ca.pem\nk6 run -o opentelemetry script.js","handlingStrategy":"validation","validationCode":"// Shell: verify PEM before the run\nca=\"${K6_OTEL_TLS_CERTIFICATE:-}\"\nif [ -n \"$ca\" ]; then\n  head -1 \"$ca\" | grep -q '^-----BEGIN CERTIFICATE-----' \\\n    || { echo \"$ca is not PEM; convert with: openssl x509 -inform der -in $ca -out $ca.pem\" >&2; exit 1; }\nfi\nk6 run -o opentelemetry script.js","typeGuard":"// Go\nfunc isPEMCert(b []byte) bool {\n    block, _ := pem.Decode(b)\n    return block != nil && block.Type == \"CERTIFICATE\"\n}","tryCatchPattern":null,"preventionTips":["Convert DER certificates to PEM once, at provisioning time, not per test run","Verify CA files with 'openssl x509 -in ca.pem -noout -subject' before wiring them into CI","Prefer re-exporting the bundle from the issuing CA over hand-editing PEM files"],"tags":["opentelemetry","tls","certificate","pem","configuration","k6"],"backgroundTag":"invalid-certificate-format","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}