When SSL starts failing “randomly” behind a corporate proxy
It usually begins quietly. A Windows workstation joins a domain, a proxy gets enforced for outbound traffic, and everything still looks fine for weeks. Then one day an internal app update fails. Next, a package manager starts throwing certificate errors. A PowerShell script that has worked for months suddenly can’t reach an API. The pattern feels inconsistent because the failures show up in different tools, at different times, and often only on certain networks.
In most corporate environments, the proxy is not just routing traffic. It is inspecting it. That inspection often involves TLS interception (sometimes called SSL inspection), where the proxy terminates and re-issues certificates on the fly. If Windows and the applications on it do not trust the proxy’s issuing certificate chain, we get SSL/TLS errors that look like “the certificate is invalid” even though the destination site is perfectly fine.
We are going to fix this the production way: by establishing trust correctly, validating the chain, and ensuring the fix persists across reboots and across the tools IT professionals actually use on Windows. We will not use bypass approaches. We will make the environment controlled and predictable.
Prerequisites and assumptions
Before we touch certificates or proxy settings, we need to be explicit about the environment. SSL/TLS troubleshooting becomes messy when we assume the wrong trust store, the wrong proxy path, or the wrong permissions.
-
Operating system: Windows 10/11 Enterprise or Pro, or Windows Server 2019/2022. The steps below use built-in tools available on modern Windows builds.
-
Permissions: We need a local administrator PowerShell session for importing certificates into the Local Machine trust stores and for changing WinHTTP proxy settings. If we are in a locked-down enterprise, we may need a change request for certificate deployment via GPO/Intune.
-
Proxy reality: We assume outbound HTTPS is routed through a corporate proxy, and that the proxy may perform TLS inspection. We also assume the proxy’s root or intermediate CA certificate exists and can be obtained from the security/network team.
-
Security posture: We will only trust the corporate inspection CA if it is an approved organizational control. Importing an unverified CA certificate is equivalent to granting it the ability to impersonate any HTTPS site for this machine.
-
Persistence: We will implement changes in the correct Windows stores and settings so they survive reboots and apply consistently to system services and user sessions.
Step 1: Confirm the proxy path and identify which stack is failing
Before we change anything, we need to confirm whether the failures are coming from WinINET (user apps like browsers), WinHTTP (system services, some PowerShell and enterprise agents), or an application-specific trust store (Java, Node.js, Python, Git, etc.). This matters because fixing only one layer often leaves “random” failures behind.
Check the user (WinINET) proxy configuration
We are going to read the current per-user proxy configuration. This tells us what most interactive applications will use.
netsh winhttp show proxy
reg query "HKCUSoftwareMicrosoftWindowsCurrentVersionInternet Settings" /v ProxyEnable
reg query "HKCUSoftwareMicrosoftWindowsCurrentVersionInternet Settings" /v ProxyServer
reg query "HKCUSoftwareMicrosoftWindowsCurrentVersionInternet Settings" /v AutoConfigURL
We have now captured the current WinHTTP proxy (first line) and the current user’s WinINET proxy settings (registry values). If WinHTTP shows “Direct access (no proxy server)” while the user proxy is set, system services may be going direct while user apps go through the proxy, which can create inconsistent behavior.
Check the system (WinHTTP) proxy configuration
We are going to confirm whether WinHTTP is configured. Many enterprise agents, Windows services, and some PowerShell scenarios rely on WinHTTP.
netsh winhttp show proxy
This confirms whether the system-wide WinHTTP stack is using a proxy. If it is not aligned with the corporate proxy requirements, we may see TLS errors, timeouts, or authentication prompts that never surface properly for services.
Capture a clean symptom from PowerShell
We are going to trigger a simple HTTPS request and capture the error. This gives us a baseline and helps distinguish certificate trust failures from proxy authentication or connectivity issues.
powershell -NoProfile -Command "$ErrorActionPreference='Stop'; try { (Invoke-WebRequest -Uri 'https://www.microsoft.com' -UseBasicParsing).StatusCode } catch { $_.Exception | Format-List * -Force }"
If the exception mentions certificate validation (for example, “The underlying connection was closed” with an inner trust error, or “Could not establish trust relationship”), we are likely dealing with a missing corporate CA in the correct trust store. If it mentions proxy authentication (407) or name resolution, we will address those in troubleshooting later.
Step 2: Obtain and validate the corporate proxy inspection CA certificate
We are going to obtain the corporate proxy’s issuing certificate (usually a Root CA, sometimes an Intermediate CA) in .cer or .crt format. In production, we should get this from the security team or the official internal PKI portal, not by exporting it from a random browser session.
Next, we will validate what we received. We want to confirm:
-
It is a CA certificate (Basic Constraints: CA=TRUE).
-
It matches the organization’s expected subject and thumbprint.
-
It is within validity dates and uses acceptable algorithms.
Inspect the certificate details
We are going to inspect a certificate file on disk. First, we will set a variable to the certificate path so the commands remain copy/paste safe.
powershell -NoProfile -Command "$CertPath = Join-Path $env:USERPROFILE 'DownloadsCorporateProxyCA.cer'; if (-not (Test-Path $CertPath)) { Write-Host 'Place the CA certificate at:' $CertPath; exit 1 }; certutil -dump $CertPath"
This prints the certificate metadata. We should look for “Basic Constraints” indicating it is a CA, and confirm the Subject/Issuer align with our corporate PKI or proxy vendor. If anything looks off, we stop here and re-validate the source.
Step 3: Import the corporate CA into the correct Windows trust stores
Now we will establish trust correctly. For TLS inspection to work without breaking SSL validation, Windows must trust the issuing CA that the proxy uses to generate on-the-fly certificates.
In production, we typically import into:
-
Local Machine Trusted Root Certification Authorities if the proxy uses a root CA to sign leaf certs.
-
Local Machine Intermediate Certification Authorities if the proxy uses an intermediate CA and the root is already trusted.
We will start by importing into the Local Machine Root store only if that is what the security team provided and approved. If the provided certificate is an intermediate, we will import it into the Intermediate store instead.
Import into Local Machine Trusted Root store (approved root CA)
We are going to import the certificate into the Local Machine Root store. This requires administrative privileges and will affect all users and services on the machine, which is what we want for consistent behavior.
powershell -NoProfile -Command ^
"$CertPath = Join-Path $env:USERPROFILE 'DownloadsCorporateProxyCA.cer'; ^
if (-not (Test-Path $CertPath)) { throw 'CA certificate not found at ' + $CertPath }; ^
Import-Certificate -FilePath $CertPath -CertStoreLocation 'Cert:LocalMachineRoot' | Format-List Subject,Thumbprint,PSParentPath"
The certificate is now installed in the Local Machine Root store. This change persists across reboots and applies to system services and user applications that rely on the Windows certificate store.
Import into Local Machine Intermediate store (approved intermediate CA)
If the security team provided an intermediate CA certificate, we should import it into the Intermediate store instead of Root. We are going to do that here as an alternative path.
powershell -NoProfile -Command ^
"$CertPath = Join-Path $env:USERPROFILE 'DownloadsCorporateProxyIntermediateCA.cer'; ^
if (-not (Test-Path $CertPath)) { Write-Host 'If using an intermediate CA, place it at:' $CertPath; exit 0 }; ^
Import-Certificate -FilePath $CertPath -CertStoreLocation 'Cert:LocalMachineCA' | Format-List Subject,Thumbprint,PSParentPath"
If we imported an intermediate CA, Windows can now build a valid chain when the proxy presents leaf certificates signed by that intermediate, assuming the corresponding root is already trusted.
Verify the certificate is present in the store
We are going to verify that the certificate is actually in the Local Machine store. This avoids the common situation where a certificate was imported into the Current User store and services still fail.
powershell -NoProfile -Command ^
"$ExpectedSubjectFragment = 'Corporate'; ^
Get-ChildItem -Path Cert:LocalMachineRoot | Where-Object { $_.Subject -like ('*' + $ExpectedSubjectFragment + '*') } | Select-Object Subject,Thumbprint,NotAfter | Format-Table -AutoSize"
This confirms the certificate is present (at least by subject fragment). In production, we should verify by thumbprint against the value provided by the security team.
Step 4: Align WinHTTP proxy settings with the corporate proxy
Even with correct trust, we can still see SSL/TLS errors if system services are not actually using the proxy path the organization expects. We are going to align WinHTTP with the current user’s proxy configuration when appropriate.
This is not a bypass. This is making the system stack consistent with the corporate network design.
Import WinINET proxy settings into WinHTTP
We are going to copy the current user’s proxy settings into WinHTTP. This is a common enterprise approach when the proxy is managed via PAC/WPAD or user policy and we need system services to follow it.
netsh winhttp import proxy source=ie
netsh winhttp show proxy
WinHTTP is now configured based on the user’s Internet Settings. The second command confirms what WinHTTP will use going forward. This persists across reboots.
Verification: test an HTTPS request using WinHTTP-backed components
We are going to test again with PowerShell. On modern Windows, PowerShell uses Windows networking and certificate validation. This gives us a practical confirmation that trust and proxy path are now aligned.
powershell -NoProfile -Command "$ErrorActionPreference='Stop'; (Invoke-WebRequest -Uri 'https://www.microsoft.com' -UseBasicParsing).StatusCode"
If we get a 200 response, we have confirmed that the machine can establish a trusted TLS connection through the proxy for this request path.
Step 5: Validate the TLS chain we are actually seeing
When a proxy performs TLS inspection, the certificate presented to the client is not the origin server’s certificate. It is a proxy-generated leaf certificate that should chain up to the corporate inspection CA we just trusted. We are going to confirm that chain from the Windows perspective.
Capture and inspect the remote certificate chain
We are going to use .NET’s SSL stream to retrieve the certificate presented for a hostname. This helps us confirm whether the proxy is intercepting and which issuer is being used.
powershell -NoProfile -Command ^
"$HostName = 'www.microsoft.com'; ^
$tcp = New-Object System.Net.Sockets.TcpClient($HostName, 443); ^
$ssl = New-Object System.Net.Security.SslStream($tcp.GetStream(), $false, ({ $true })); ^
$ssl.AuthenticateAsClient($HostName); ^
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($ssl.RemoteCertificate); ^
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain; ^
$null = $chain.Build($cert); ^
'Subject: ' + $cert.Subject; ^
'Issuer: ' + $cert.Issuer; ^
'Chain:'; ^
$chain.ChainElements | ForEach-Object { ' - ' + $_.Certificate.Subject + ' | Thumbprint=' + $_.Certificate.Thumbprint }; ^
$ssl.Dispose(); $tcp.Close()"
This prints the Subject, Issuer, and the chain elements. If the Issuer or chain includes the corporate proxy CA, interception is active and Windows is now able to build the chain. If the chain build fails in other tools, that points to application-specific trust stores, which we will address next.
Step 6: Handle application-specific trust stores on Windows
Many enterprise tools do not rely exclusively on the Windows certificate store. This is where teams get stuck: browsers work, but Git fails; PowerShell works, but Java apps fail; Windows Update works, but a CI agent fails.
We will focus on real-world fixes that keep security intact: we will add the corporate CA to the trust store that the application actually uses, or configure the application to use the Windows trust store where supported.
Git for Windows (common in enterprise automation)
We are going to check whether Git is using the Windows certificate store or its bundled CA bundle. If it uses a bundled bundle, it may not include the corporate inspection CA.
First, we will inspect Git’s SSL configuration.
git config --system --get http.sslBackend
git config --system --get http.sslCAInfo
git config --global --get http.sslBackend
git config --global --get http.sslCAInfo
This shows whether Git is configured to use a specific SSL backend or CA file. If Git is already using the Windows store (often via schannel), it should benefit from the Local Machine CA import we did earlier. If it is pinned to a CA bundle file, we need to update that file in a controlled way approved by policy.
Java (JRE/JDK truststore)
Java commonly uses its own truststore (cacerts). If a Java-based tool fails with PKIX path building errors, we need to import the corporate CA into the Java truststore used by that runtime.
First, we will locate Java and print the active Java home. This avoids guessing which runtime is in use.
where java
powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable('JAVA_HOME','Machine'); [Environment]::GetEnvironmentVariable('JAVA_HOME','User')"
Now we know which Java executable is being used and whether JAVA_HOME is set. If we have a managed JDK, we should coordinate changes because updating cacerts can be overwritten by upgrades.
Node.js (varies by distribution and tooling)
Node.js tooling sometimes uses OpenSSL with its own CA handling. In enterprise environments, the most stable approach is to ensure the corporate CA is trusted by the OS and then confirm whether the Node distribution respects the OS store. If a specific tool bundles its own CA set, we need to manage that tool’s trust configuration through its supported enterprise mechanism.
We will start by confirming Node is present and its version, because behavior can differ across versions and packaging.
where node
node --version
This confirms which Node binary is in use. If Node-based tools still fail after OS trust is fixed, we should treat it as an application-specific trust issue and manage it through the tool’s documented enterprise configuration rather than weakening TLS validation.
Firewall and network considerations
SSL/TLS errors are sometimes a symptom of network controls rather than trust. On Windows, local firewall rules can block proxy connectivity, and enterprise endpoint security can intercept or filter TLS in ways that look like certificate failures.
We are going to verify that outbound connectivity to the proxy is not being blocked locally. We will not open broad rules; we will only observe and confirm.
Check Windows Firewall profiles and outbound policy
We are going to read the firewall profile status and default outbound action. This helps us understand whether the machine is in a restrictive posture that could affect proxy reachability.
netsh advfirewall show allprofiles
powershell -NoProfile -Command "Get-NetFirewallProfile | Select-Object Name,Enabled,DefaultOutboundAction,DefaultInboundAction | Format-Table -AutoSize"
This confirms whether outbound is allowed by default and which profiles are active. If outbound is blocked by default, we need explicit allow rules for the proxy endpoints and ports, managed through enterprise policy.
Troubleshooting: symptoms, likely causes, and real fixes
Symptom: “The underlying connection was closed: Could not establish trust relationship”
-
Likely cause: The corporate proxy is intercepting TLS and Windows does not trust the proxy’s issuing CA.
-
Fix: Import the approved corporate proxy CA into Cert:LocalMachineRoot (or intermediate into Cert:LocalMachineCA) and verify chain building using the SSL stream check in Step 5.
Symptom: Browser works, but PowerShell/agents fail (or the reverse)
-
Likely cause: WinINET proxy settings differ from WinHTTP proxy settings, so different components take different network paths.
-
Fix: Align WinHTTP with the user proxy using netsh winhttp import proxy source=ie, then confirm with netsh winhttp show proxy and re-test the failing component.
Symptom: “407 Proxy Authentication Required” or repeated auth prompts
-
Likely cause: Proxy requires authentication and the failing component cannot prompt interactively (services, scheduled tasks), or credentials are not available in that context.
-
Fix: Ensure the proxy authentication method is compatible with non-interactive contexts (enterprise proxy policy), and ensure the service account has the required access. Also confirm WinHTTP proxy settings are correct for the service context.
Symptom: “CERTIFICATE_VERIFY_FAILED” in a specific tool, but Windows trust looks correct
-
Likely cause: The tool uses its own CA bundle or truststore (Java, some Git/Node/Python distributions).
-
Fix: Identify the tool’s trust mechanism and add the corporate CA through its supported configuration or truststore management. Avoid weakening TLS verification; instead, make trust explicit and auditable.
Symptom: Intermittent SSL failures depending on network (office vs VPN vs home)
-
Likely cause: Different proxy paths or different inspection policies across networks, or PAC/WPAD changes that alter routing.
-
Fix: Confirm the active proxy configuration on each network (registry + WinHTTP), confirm the presented certificate issuer via Step 5, and ensure the correct corporate CA chain is installed for each inspection domain.
Common mistakes
-
Mistake: Importing the CA into Current User instead of Local Machine.
Symptom: Browser works for one user, but services, scheduled tasks, or other users still fail with trust errors.
Fix: Import into Cert:LocalMachineRoot (or Cert:LocalMachineCA for intermediates) and re-test.
-
Mistake: Trusting an unverified CA certificate obtained from an untrusted source.
Symptom: SSL errors disappear, but the machine is now vulnerable to man-in-the-middle by any party holding that CA key.
Fix: Only install CA certificates provided and validated by the organization. Verify thumbprints against an authoritative channel.
-
Mistake: Fixing only the proxy setting or only the certificate trust, not both.
Symptom: Some tools recover while others continue failing, creating the illusion of randomness.
Fix: Confirm WinINET and WinHTTP proxy alignment, then confirm certificate chain trust, then address application-specific trust stores.
-
Mistake: Assuming “SSL error” always means “certificate problem.”
Symptom: Errors persist after CA import, especially with timeouts or 407 responses.
Fix: Check proxy authentication requirements, firewall posture, DNS resolution, and whether the proxy is reachable from the failing context.
How do we at NIILAA look at this
This setup is not impressive because it is complex. It is impressive because it is controlled. Every component is intentional. Every configuration has a reason. This is how infrastructure should scale — quietly, predictably, and without drama.
At NIILAA, we help organizations design, deploy, secure, and maintain proxy-aware Windows environments where TLS inspection, certificate trust, and application behavior are aligned by policy. That means fewer “random” outages, faster incident resolution, and changes that remain stable across upgrades, reboots, and enterprise tooling.
-
Website: https://www.niilaa.com
-
Email: [email protected]
-
LinkedIn: https://www.linkedin.com/company/niilaa
-
Facebook: https://www.facebook.com/niilaa.llc