Command-line tools

PowerShell "Could not create SSL/TLS secure channel": fix

By · Last verified

Error messageThe request was aborted: Could not create SSL/TLS secure channel.

The request was aborted: Could not create SSL/TLS secure channel. means Windows PowerShell (or another .NET Framework program) could not complete a TLS handshake with the server. Usually the session offers only SSL 3 or TLS 1.0, and the server requires TLS 1.2 or later. Turn on TLS 1.2 the supported way; certificate checks are not the problem.

What the error means

The .NET Framework TLS handshake failed before any request was sent. In .NET Framework, HttpWebRequest, WebClient and the Windows PowerShell 5.1 cmdlets Invoke-WebRequest and Invoke-RestMethod throw a WebException with status SecureChannelFailure. Its text combines two reference-source strings, "The request was aborted: {0}." and "Could not create SSL/TLS secure channel", into the message you see:

Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.

.NET Framework hands TLS to Windows Schannel, so the OS version decides which protocols are possible, and .NET Framework settings decide which of those the process offers. Microsoft's guidance is that apps targeting .NET Framework 4.7 or later use the OS default; processes that target older framework versions, or machines without the SchUseStrongCrypto and SystemDefaultTlsVersions registry values, may offer only old protocols.

A trust failure looks different: Could not establish trust relationship for the SSL/TLS secure channel. If that is your message, protocol negotiation worked and the server certificate was rejected; see .NET remote certificate is invalid.

Causes, most common first

A session that does not offer TLS 1.2 is the most common cause.

1. The session does not offer TLS 1.2

  • Confirm:
[Net.ServicePointManager]::SecurityProtocol
$PSVersionTable.PSVersion

Output such as Ssl3, Tls means TLS 1.2 is not offered. SystemDefault or a list containing Tls12 means this is not your cause.

  • Fix: enable TLS 1.2 for the session, or machine-wide through the registry (commands below).

2. The Windows version cannot speak what the server requires

Microsoft's Schannel table shows TLS 1.1 and 1.2 disabled by default on Windows 7 and Server 2008 R2, and TLS 1.3 supported only from Windows 11 and Windows Server 2022. A server that accepts only TLS 1.3, or only cipher suites the old Windows build lacks, cannot be reached.

  • Confirm: check the server's protocols and cipher suites with the SSL checker; on the client run Get-TlsCipherSuite | Select-Object Name (Windows 10 / Server 2016 and later).
  • Fix: enable TLS 1.2 in Schannel on old systems, ask the server owner to keep TLS 1.2 with ECDHE-GCM suites, or upgrade Windows.

3. Schannel protocols were disabled by hardening

Security baselines and hardening tools write Enabled=0 under HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client.

  • Confirm:
Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -ErrorAction SilentlyContinue

4. The server requires a client certificate

With mutual TLS, a missing client certificate, or one whose private key the account running PowerShell cannot read, fails the handshake. Pass it with -Certificate and check private key permissions in certlm.msc.

5. A proxy or firewall interferes

If the same command works from another network, a proxy or firewall is cutting the handshake. See Windows Schannel errors for reading the System event log entries Schannel writes.

Fix commands by platform

Every fix makes the client offer TLS 1.2: per session, machine-wide for .NET Framework, or in Schannel on old Windows.

Windows PowerShell 5.1, current session only:

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest https://example.com/ -UseBasicParsing

Machine-wide for all .NET Framework 4.x apps (elevated PowerShell, then restart the apps):

$keys = 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319'
foreach ($k in $keys) {
    New-ItemProperty -Path $k -Name SchUseStrongCrypto -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path $k -Name SystemDefaultTlsVersions -Value 1 -PropertyType DWord -Force | Out-Null
}

These are the values Microsoft lists as the safest settings. They affect every .NET Framework application on the machine, which is the point, but test line-of-business apps afterwards.

Old Windows (7 / Server 2008 R2): enable TLS 1.2 for Schannel clients:

$p = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client'
New-Item -Path $p -Force | Out-Null
New-ItemProperty -Path $p -Name Enabled -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path $p -Name DisabledByDefault -Value 0 -PropertyType DWord -Force | Out-Null

Reboot afterwards. These systems are out of support; plan to replace them.

PowerShell 7 (pwsh): its web cmdlets use HttpClient and the OS defaults. If you must restrict versions, use -SslProtocol:

Invoke-RestMethod https://example.com/api -SslProtocol Tls12

Errors there look like the .NET message covered in The SSL connection could not be established.

Don't disable certificate verification

[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } in Windows PowerShell, or -SkipCertificateCheck in PowerShell 7, will not fix a protocol failure, and they make every request in the session accept forged certificates. Microsoft's own documentation for -SkipCertificateCheck says it isn't secure and is meant only for known hosts with self-signed certificates in testing. Also do not add Ssl3 or Tls to SecurityProtocol "for compatibility"; that re-enables deprecated protocols.

The safer alternatives are: offer TLS 1.2 (session line or registry), keep SystemDefault where possible, update or replace systems that cannot do TLS 1.2, and fix trust problems by installing the right root certificate, not by skipping checks.

Verify the fix

[Net.ServicePointManager]::SecurityProtocol
(Invoke-WebRequest https://example.com/ -UseBasicParsing).StatusCode

The first line should list Tls12 (or SystemDefault after the registry change and a new PowerShell window), and the request should return 200 or another HTTP status instead of the exception. For background on what TLS 1.3 changes, see TLS 1.3 explained; if you control the server, the TLS config generator produces a configuration that both old and new clients can use.

FAQ

What is the difference between Could not create and Could not establish trust relationship?

Could not create SSL/TLS secure channel is a handshake failure: protocols, cipher suites, client certificates or a dropped connection. Could not establish trust relationship for the SSL/TLS secure channel means the handshake worked but the server certificate was not trusted. The second one is fixed with certificates, the first one with protocol settings.

Should I add the ServicePointManager line to every script?

It is a reasonable stopgap for scripts you run on old machines. The durable fix is the registry values SchUseStrongCrypto and SystemDefaultTlsVersions, which make every .NET Framework application on the machine use the OS defaults, or moving the script to PowerShell 7.

Why does it work in a browser on the same Windows server?

Browsers ship their own TLS settings and enable TLS 1.2 and 1.3 regardless of .NET Framework defaults. Windows PowerShell 5.1 uses .NET Framework's ServicePointManager, whose protocol list depends on the framework version the process targets and on the registry values.

Can this be a server problem?

Yes. If the server only accepts TLS 1.3, Windows 10 and Windows Server 2019 cannot connect at all because Schannel supports TLS 1.3 only from Windows 11 and Windows Server 2022. A server limited to cipher suites that older Windows versions lack causes the same error. Check the server in the SSL checker.

Sources

  1. Microsoft Learn: TLS best practices with .NET Framework
  2. Microsoft Learn: Protocols in TLS/SSL (Schannel SSP)
  3. Microsoft Learn: Invoke-WebRequest (SslProtocol, SkipCertificateCheck)
  4. Microsoft Learn: Differences between Windows PowerShell 5.1 and PowerShell 7.x
  5. Microsoft Learn: WebExceptionStatus enum (SecureChannelFailure, TrustFailure)