{"record":{"id":"a3135ded5a700b11","repo":"BeyondDimension/SteamTools","slug":"could-not-remove-certificate-as-it-is-null-or-empt","errorCode":null,"errorMessage":"Could not remove certificate as it is null or empty.","messagePattern":"Could not remove certificate as it is null or empty\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Certificate/CertificateManagerImpl.cs","lineNumber":159,"sourceCode":"\n        //var rootCertificateName = CertificateConstants.RootCertificateName;\n\n        RootCertificate = CertGenerator.GenerateBySelfPfx(\n            null,\n            validFrom,\n            validTo,\n            Interface.PfxFilePath,\n            GetPfxPassword());\n        RootCertificatePackable = X509CertificatePackable.CreateX509Certificate2(Interface.PfxFilePath, GetPfxPassword(), X509KeyStorageFlags.Exportable);\n\n        return RootCertificate != null;\n    }\n\n    void SharedRemoveTrustedRootCertificate()\n    {\n        if (RootCertificate == null)\n        {\n            throw new ApplicationException(\n                \"Could not remove certificate as it is null or empty.\");\n        }\n\n        using var x509Store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);\n\n        try\n        {\n            x509Store.Open(OpenFlags.ReadWrite);\n            foreach (var item in x509Store.Certificates.Find(X509FindType.FindBySubjectName, CertificateConstants.RootCertificateName, false))\n            {\n                //if (item.Thumbprint == RootCertificate.Thumbprint)\n                //{\n                x509Store.Remove(item);\n                //}\n            }\n            //x509Store.Remove(RootCertificate);\n        }\n        catch (Exception e)","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/BeyondDimension/SteamTools/blob/c16ffa08e03b192d23ada290c4969e77f9201f3d/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Certificate/CertificateManagerImpl.cs#L141-L177","documentation":"Thrown by SharedRemoveTrustedRootCertificate when RootCertificate is null while attempting to remove the root cert from the LocalMachine Root store. Removal needs the in-memory certificate object (or at least that it was loaded); if nothing was loaded the uninstall step cannot proceed safely.","triggerScenarios":"Calling the remove path when RootCertificate was never loaded — e.g. during uninstall/cleanup on a system where the PFX was already deleted, generation never ran, or a prior load failed and returned null.","commonSituations":"User deleted the PFX manually before uninstalling; cleanup runs after a failed install that never produced a cert; profile/cert store reset left the app with no loaded cert; calling remove on a fresh install that never trusted anything.","solutions":["Load or regenerate RootCertificate before calling remove, or skip removal when it is already null.","If the cert is already gone from the store, treat null as a no-op success instead of throwing.","Restore the PFX from backup (with correct password) so it can be loaded for removal.","Guard the remove call with a null check and log a warning rather than aborting cleanup."],"exampleFix":"// before\nSharedRemoveTrustedRootCertificate(); // throws if RootCertificate == null\n\n// after\nif (RootCertificate == null)\n{\n    Log.Warning(TAG, \"RootCertificate null; nothing to remove.\");\n    return;\n}\nSharedRemoveTrustedRootCertificate();","handlingStrategy":"validation","validationCode":"// Treat a missing cert as a no-op during cleanup instead of throwing.\nif (certificateManager.RootCertificate == null)\n{\n    Log.Warning(TAG, \"RootCertificate is null; skipping removal (already gone).\");\n    return;\n}\ncertificateManager.SharedRemoveTrustedRootCertificate();","typeGuard":"bool CanRemoveCertificate(ICertificateManager mgr) => mgr.RootCertificate != null;","tryCatchPattern":"try { certificateManager.SharedRemoveTrustedRootCertificate(); }\ncatch (ApplicationException ex) when (ex.Message.Contains(\"null or empty\"))\n{\n    Log.Information(TAG, \"No loaded certificate to remove; uninstall proceeding.\");\n    // cleanup is effectively already done\n}","preventionTips":["During uninstall, tolerate a missing cert (idempotent removal) rather than failing the whole uninstall.","Load the cert from PFX before removal; if the PFX is gone, remove by subject name from the store instead.","Keep the PFX until uninstall completes; do not delete it before the remove step.","Make removal best-effort and log, so a null cert never blocks cleanup."],"tags":["certificate","tls","windows","cleanup"],"backgroundTag":null,"analyzedSha":"c16ffa08e03b192d23ada290c4969e77f9201f3d","analyzedAt":"2026-08-13T11:52:20.410Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}