{"record":{"id":"5d40265bc742c281","repo":"hashicorp/nomad","slug":"both-client-cert-and-client-key-must-be-provided","errorCode":null,"errorMessage":"Both client cert and client key must be provided","messagePattern":"Both client cert and client key must be provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/api.go","lineNumber":465,"sourceCode":"\tif tlsConfig == nil {\n\t\treturn nil\n\t}\n\tif httpClient == nil {\n\t\treturn errors.New(\"config HTTP Client must be set\")\n\t}\n\n\tvar clientCert tls.Certificate\n\tfoundClientCert := false\n\tif tlsConfig.ClientCert != \"\" || tlsConfig.ClientKey != \"\" {\n\t\tif tlsConfig.ClientCert != \"\" && tlsConfig.ClientKey != \"\" {\n\t\t\tvar err error\n\t\t\tclientCert, err = tls.LoadX509KeyPair(tlsConfig.ClientCert, tlsConfig.ClientKey)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfoundClientCert = true\n\t\t} else {\n\t\t\treturn errors.New(\"Both client cert and client key must be provided\")\n\t\t}\n\t} else if len(tlsConfig.ClientCertPEM) != 0 || len(tlsConfig.ClientKeyPEM) != 0 {\n\t\tif len(tlsConfig.ClientCertPEM) != 0 && len(tlsConfig.ClientKeyPEM) != 0 {\n\t\t\tvar err error\n\t\t\tclientCert, err = tls.X509KeyPair(tlsConfig.ClientCertPEM, tlsConfig.ClientKeyPEM)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfoundClientCert = true\n\t\t} else {\n\t\t\treturn errors.New(\"Both client cert and client key must be provided\")\n\t\t}\n\t}\n\n\tclientTLSConfig := httpClient.Transport.(*http.Transport).TLSClientConfig\n\trootConfig := &rootcerts.Config{\n\t\tCAFile:        tlsConfig.CACert,\n\t\tCAPath:        tlsConfig.CAPath,","sourceCodeStart":447,"sourceCodeEnd":483,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/api/api.go#L447-L483","documentation":"Returned by ConfigureTLS when the TLS config supplies only one of ClientCert or ClientKey file paths. Mutual-TLS client authentication requires the certificate and its private key to be loaded as a pair via tls.LoadX509KeyPair, so a half-configured pair is rejected before any connection is made.","triggerScenarios":"Thrown at api/api.go:465 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Set both TLSConfig.ClientCert and TLSConfig.ClientKey to the PEM cert and key file paths","Alternatively use ClientCertPEM/ClientKeyPEM in-memory fields, both together"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}