{"record":{"id":"7d04084f662c8700","repo":"kopia/kopia","slug":"unable-to-initialize-client-cert-credential","errorCode":null,"errorMessage":"unable to initialize client cert credential","messagePattern":"unable to initialize client cert credential","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"repo/blob/azure/azure_storage.go","lineNumber":462,"sourceCode":"\t\t)\n\t// client secret\n\tcase opt.TenantID != \"\" && opt.ClientID != \"\" && opt.ClientSecret != \"\":\n\t\tcred, err := azidentity.NewClientSecretCredential(opt.TenantID, opt.ClientID, opt.ClientSecret, nil)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"unable to initialize client secret credential\")\n\t\t}\n\n\t\tservice, serviceErr = azblob.NewClient(fmt.Sprintf(\"%s://%s/\", protocol, storageHostname), cred, clientOptions)\n\t// client certificate\n\tcase opt.TenantID != \"\" && opt.ClientID != \"\" && opt.ClientCertificate != \"\":\n\t\tcerts, key, certErr := azidentity.ParseCertificates([]byte(opt.ClientCertificate), nil)\n\t\tif certErr != nil {\n\t\t\treturn nil, errors.Wrap(certErr, \"failed to read client cert\")\n\t\t}\n\n\t\tcred, credErr := azidentity.NewClientCertificateCredential(opt.TenantID, opt.ClientID, certs, key, nil)\n\t\tif credErr != nil {\n\t\t\treturn nil, errors.Wrap(credErr, \"unable to initialize client cert credential\")\n\t\t}\n\n\t\tservice, serviceErr = azblob.NewClient(fmt.Sprintf(\"%s://%s/\", protocol, storageHostname), cred, clientOptions)\n\t// Azure Federated Token\n\tcase opt.TenantID != \"\" && opt.ClientID != \"\" && opt.AzureFederatedTokenFile != \"\":\n\t\tcred, err := azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{\n\t\t\tClientID:      opt.ClientID,\n\t\t\tTenantID:      opt.TenantID,\n\t\t\tTokenFilePath: opt.AzureFederatedTokenFile,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"unable to initialize Azure Federated Identity workload identity credential\")\n\t\t}\n\n\t\tservice, serviceErr = azblob.NewClient(fmt.Sprintf(\"%s://%s/\", protocol, storageHostname), cred, clientOptions)\n\tdefault:\n\t\treturn nil, errors.New(\"one of the storage key, SAS token, client secret, client certificate, or Azure Federated Token file must be provided\")\n\t}","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/repo/blob/azure/azure_storage.go#L444-L480","documentation":"getAZService wraps azidentity.NewClientCertificateCredential, which builds a service-principal credential from the parsed certificate and key. This error means the credential object could not be constructed even though the certificate parsed — typically an invalid key, mismatched cert/key pair, or invalid tenant/client IDs.","triggerScenarios":"After ParseCertificates succeeds, NewClientCertificateCredential fails due to a malformed private key, cert/key mismatch, empty or malformed TenantID/ClientID, or invalid option values.","commonSituations":"Private key encrypted with a passphrase (unparseable without password); certificate and key from different principals; client certificate not uploaded/registered on the Azure AD app; GUID fields containing typos.","solutions":["Ensure the private key is decrypted (no passphrase) and matches the certificate (compare moduli)","Confirm the certificate is uploaded to the service principal in Azure AD (az ad app credential reset with --cert)","Validate TenantID and ClientID are correct GUIDs for the principal","Re-export cert+key together with openssl and re-parse before retrying","Use az login --service-principal --certificate as an out-of-band check"],"exampleFix":"// before\nopenssl pkcs12 -in cert.pfx -nocerts -out key.pem // encrypted key\n// after\nopenssl pkcs12 -in cert.pfx -nocerts -nodes -out key.pem // decrypted key\n// then verify match:\n// openssl x509 -noout -modulus -in cert.pem | openssl md5\n// openssl rsa  -noout -modulus -in key.pem  | openssl md5","handlingStrategy":"validation","validationCode":"func validateCertCredential(tenantID, clientID, certPEM string) error {\n    if _, err := uuid.Parse(strings.TrimSpace(tenantID)); err != nil {\n        return fmt.Errorf(\"tenant id invalid: %w\", err)\n    }\n    if _, err := uuid.Parse(strings.TrimSpace(clientID)); err != nil {\n        return fmt.Errorf(\"client id invalid: %w\", err)\n    }\n    // key must be unencrypted and match the cert\n    if strings.Contains(certPEM, \"ENCRYPTED\") {\n        return errors.New(\"private key must be decrypted (no passphrase)\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Export the private key unencrypted (-nodes) when generating","Verify cert/key match (compare modulus hashes)","Upload the certificate to the Azure AD app registration","Validate tenant/client GUIDs before constructing the credential"],"tags":["azure","authentication","certificate","service-principal"],"backgroundTag":"invalid-credentials","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}