{"record":{"id":"101d347d84f848d8","repo":"opentofu/opentofu","slug":"cannot-load-client-certificate-w","errorCode":null,"errorMessage":"cannot load client certificate: %w","messagePattern":"cannot load client certificate: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/http/backend.go","lineNumber":201,"sourceCode":"\tvar tlsConfig tls.Config\n\tclient.HTTPClient.Transport.(*http.Transport).TLSClientConfig = &tlsConfig\n\n\tif skipCertVerification {\n\t\t// ignores TLS verification\n\t\ttlsConfig.InsecureSkipVerify = true\n\t}\n\tif clientCACertificatePem != \"\" {\n\t\t// trust servers based on a CA\n\t\ttlsConfig.RootCAs = x509.NewCertPool()\n\t\tif !tlsConfig.RootCAs.AppendCertsFromPEM([]byte(clientCACertificatePem)) {\n\t\t\treturn errors.New(\"failed to append certs\")\n\t\t}\n\t}\n\tif clientCertificatePem != \"\" && clientPrivateKeyPem != \"\" {\n\t\t// attach a client certificate to the TLS handshake (aka mTLS)\n\t\tcertificate, err := tls.X509KeyPair([]byte(clientCertificatePem), []byte(clientPrivateKeyPem))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot load client certificate: %w\", err)\n\t\t}\n\t\ttlsConfig.Certificates = []tls.Certificate{certificate}\n\t}\n\n\treturn nil\n}\n\nfunc (b *Backend) configure(ctx context.Context) error {\n\tdata := schema.FromContextBackendConfig(ctx)\n\n\taddress := data.Get(\"address\").(string)\n\tupdateURL, err := url.Parse(address)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse address URL: %w\", err)\n\t}\n\tif updateURL.Scheme != \"http\" && updateURL.Scheme != \"https\" {\n\t\treturn fmt.Errorf(\"address must be HTTP or HTTPS\")\n\t}","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/backend/remote-state/http/backend.go#L183-L219","documentation":"With both client_certificate_pem and client_private_key_pem set, configureTLS calls tls.X509KeyPair on the two PEM blobs and wraps any failure as 'cannot load client certificate'. X509KeyPair fails when either blob is not a well-formed PEM certificate/key block, or when the private key does not correspond to the certificate.","triggerScenarios":"PEM data missing its -----BEGIN/END----- fences, cert and key files swapped between the two attributes, a key generated for a different certificate, or extraneous text interleaved with the base64 body.","commonSituations":"file() reading the wrong path or a truncated file; passphrase-encrypted keys the loader cannot parse; rotating the cert but not the key; PEMs mangled by templating or copy-paste line wrapping.","solutions":["Check the pair matches: 'openssl x509 -in client.crt -noout -modulus | openssl md5' and 'openssl rsa -in client.key -noout -modulus | openssl md5' must print the same hash","Confirm both files are PEM with proper -----BEGIN CERTIFICATE----- / -----BEGIN PRIVATE KEY----- fences and no interleaved text or truncation","Re-issue the cert/key pair together if they came from different CSAs and redeploy"],"exampleFix":"# before (cert and key from different issuages)\nclient_certificate_pem = file(\"new-client.crt\")\nclient_private_key_pem = file(\"old-client.key\")\n# after\nclient_certificate_pem = file(\"new-client.crt\")\nclient_private_key_pem = file(\"new-client.key\")","handlingStrategy":"validation","validationCode":"// Verify the PEM pair loads as an X509KeyPair before tofu init\ncertPEM, errCert := os.ReadFile(\"client.crt\")\nkeyPEM, errKey := os.ReadFile(\"client.key\")\nif errCert == nil && errKey == nil {\n    if _, err := tls.X509KeyPair(certPEM, keyPEM); err != nil {\n        log.Fatalf(\"bad mTLS pair: %v\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify cert/key modulus hashes match after any rotation (openssl md5 of the modulus)","Keep PEM fences intact; do not wrap base64 lines when pasting through ticketing systems","Rotate certificate and key together, never independently"],"tags":["http","backend","tls","mtls","pem","x509"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}