{"record":{"id":"f51fd5d35518efe7","repo":"hashicorp/terraform","slug":"client-certificate-pem-is-set-but-client-private-k","errorCode":null,"errorMessage":"client_certificate_pem is set but client_private_key_pem is not","messagePattern":"client_certificate_pem is set but client_private_key_pem is not","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/http/backend.go","lineNumber":276,"sourceCode":"\t\tbackendbase.GetAttrDefault(configVal, \"skip_cert_verification\", cty.False),\n\t)\n\tclientCACertificatePem := backendbase.GetAttrEnvDefaultFallback(\n\t\tconfigVal, \"client_ca_certificate_pem\",\n\t\t\"TF_HTTP_CLIENT_CA_CERTIFICATE_PEM\", cty.StringVal(\"\"),\n\t).AsString()\n\tclientCertificatePem := backendbase.GetAttrEnvDefaultFallback(\n\t\tconfigVal, \"client_certificate_pem\",\n\t\t\"TF_HTTP_CLIENT_CERTIFICATE_PEM\", cty.StringVal(\"\"),\n\t).AsString()\n\tclientPrivateKeyPem := backendbase.GetAttrEnvDefaultFallback(\n\t\tconfigVal, \"client_private_key_pem\",\n\t\t\"TF_HTTP_CLIENT_PRIVATE_KEY_PEM\", cty.StringVal(\"\"),\n\t).AsString()\n\tif !skipCertVerification && clientCACertificatePem == \"\" && clientCertificatePem == \"\" && clientPrivateKeyPem == \"\" {\n\t\treturn nil\n\t}\n\tif clientCertificatePem != \"\" && clientPrivateKeyPem == \"\" {\n\t\treturn fmt.Errorf(\"client_certificate_pem is set but client_private_key_pem is not\")\n\t}\n\tif clientPrivateKeyPem != \"\" && clientCertificatePem == \"\" {\n\t\treturn fmt.Errorf(\"client_private_key_pem is set but client_certificate_pem is not\")\n\t}\n\n\t// TLS configuration is needed; create an object and configure it\n\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\")","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/http/backend.go#L258-L294","documentation":"In configureTLS, client_certificate_pem (or TF_HTTP_CLIENT_CERTIFICATE_PEM) is non-empty while client_private_key_pem (or TF_HTTP_CLIENT_PRIVATE_KEY_PEM) is empty. mTLS requires BOTH a certificate and its matching private key; providing only the certificate is an incomplete, unusable configuration.","triggerScenarios":"Certificate supplied via the backend block or env var, but the matching private key was omitted or its env var was not exported.","commonSituations":"Key lives in a different secret not wired into the pipeline; the key line was dropped during copy-paste; cert and key stored in separate stores and only one was referenced.","solutions":["Set client_private_key_pem to the PEM private key matching the certificate.","If you do not need mTLS, remove client_certificate_pem entirely.","Verify both TF_HTTP_CLIENT_CERTIFICATE_PEM and TF_HTTP_CLIENT_PRIVATE_KEY_PEM are exported together."],"exampleFix":"// before\nclient_certificate_pem = file(\"client.crt\")\n// client_private_key_pem missing\n// after\nclient_certificate_pem = file(\"client.crt\")\nclient_private_key_pem = file(\"client.key\")","handlingStrategy":"validation","validationCode":"# Pre-flight: cert and key must both be set (or both unset)\ncert=\"${TF_HTTP_CLIENT_CERTIFICATE_PEM:-}\"\nkey=\"${TF_HTTP_CLIENT_PRIVATE_KEY_PEM:-}\"\nif [ -n \"$cert\" ] && [ -z \"$key\" ]; then\n  echo \"ERROR: client_certificate_pem set but client_private_key_pem is empty\"; exit 1\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always configure client_certificate_pem and client_private_key_pem as a pair.","If mTLS is not needed, leave both unset rather than supplying only one.","In CI, assert both TF_HTTP_CLIENT_*_PEM vars are exported together."],"tags":["config","tls","mtls","http-backend","validation"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}