git-ecosystem/git-credential-manager · error · Trace2FileNotFoundException

Custom certificate bundle not found at path

Error message

Custom certificate bundle not found at path: {0}

What it means

HttpClientFactory.CreateClient validates the custom certificate bundle path from configuration (http.sslCAInfo / customCertBundle) using the injected filesystem; if the file does not exist it throws Trace2FileNotFoundException. This prevents silently running TLS without the intended CA bundle.

Solutions

  1. Verify the path in the message exists: ls <path> — fix typos in the configured bundle path
  2. Point the config (http.sslCAInfo / GCM_SSL_CA_INFO) at an existing PEM bundle
  3. Copy/ship the CA bundle into the environment (container image, mounted volume)
  4. Remove the custom bundle setting if the default OS certificate store should be used instead

Example fix

// before
git config --global http.sslCAInfo /etc/ssl/company-ca.pem // file missing
// after
ls /etc/ssl/company-ca.pem || echo missing
# install the bundle or:
git config --global --unset http.sslCAInfo
Defensive patterns

Strategy: validation

Validate before calling

var bundlePath = config.Get("http.sslCAInfo");
if (!string.IsNullOrEmpty(bundlePath) && !File.Exists(bundlePath))
    throw new FileNotFoundException($"Custom certificate bundle not found: {bundlePath}");

Type guard

bool BundleExists(string path) => !string.IsNullOrEmpty(path) && File.Exists(path);

Try / catch

try
{
    var client = factory.CreateClient();
}
catch (Trace2FileNotFoundException ex) when (ex.Message.StartsWith("Custom certificate bundle not found"))
{
    logger.LogError(ex, "Fix http.sslCAInfo/GCM_SSL_CA_INFO path or unset it to use the OS store");
}

Prevention

When it happens

Trigger: Creating an HTTP client when a custom certificate bundle path is configured but the file is absent at that path (typo, deleted file, container image missing the CA file).

Common situations: Corporate proxy setups with a custom CA bundle, GCM_SSL_CA_INFO or http.sslCAInfo pointing at a path not mounted in the environment, or moving configs between machines.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/31286592d668f969. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/HttpClientFactory.cs:117

                _console.WriteWarning("| TLS certificate verification has been disabled! |");
                _console.WriteWarning("---------------------------------------------------");
                _console.WriteWarning($"HTTPS connections may not be secure. See {Constants.HelpUrls.GcmTlsVerification} for more information.");

                handler.ServerCertificateCustomValidationCallback = (req, cert, chain, errors) => true;
            }
            // If schannel is the TLS backend, custom certificate usage must be explicitly enabled
            else if (!string.IsNullOrWhiteSpace(_settings.CustomCertificateBundlePath) &&
                ((_settings.TlsBackend != TlsBackend.Schannel) || _settings.UseCustomCertificateBundleWithSchannel))
            {
                string certBundlePath = _settings.CustomCertificateBundlePath;
                _trace.WriteLine($"Custom certificate verification has been enabled with certificate bundle at {certBundlePath}");

                // Throw exception if cert bundle file not found
                if (!_fileSystem.FileExists(certBundlePath))
                {
                    var format = "Custom certificate bundle not found at path: {0}";
                    var message = string.Format(format, certBundlePath);
                    throw new Trace2FileNotFoundException(_trace2, message, format, certBundlePath);
                }

                Func<X509Certificate2, X509Chain, SslPolicyErrors, bool> validationCallback = (cert, chain, errors) =>
                {
                    // Fail immediately if there are non-chain issues with the remote cert
                    if ((errors & ~SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                    {
                        return false;
                    }

                    // Import the custom certs
                    X509Certificate2Collection certBundle = new X509Certificate2Collection();
                    certBundle.ImportFromPemFile(certBundlePath);

                    try
                    {
                        // Add the certs to the chain
                        chain.ChainPolicy.ExtraStore.AddRange(certBundle);

View on GitHub (pinned to e8ce762cd0)