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

> Windows PowerShell and .NET Framework could not negotiate TLS with the server, usually because TLS 1.2 is not offered. Enable it the supported way.

Source: https://ssl.sh/errors/powershell-could-not-create-ssl-tls-secure-channel/
Last updated: 2026-11-10

**`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:

```text
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](https://ssl.sh/errors/dotnet-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:**

```powershell
[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](https://ssl.sh/tools/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:**

```powershell
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](https://ssl.sh/errors/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:**

```powershell
[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):**

```powershell
$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:**

```powershell
$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`:

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

Errors there look like the .NET message covered in [The SSL connection could not be established](https://ssl.sh/errors/dotnet-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

```powershell
[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](https://ssl.sh/learn/tls-1-3/); if you control the server, the [TLS config generator](https://ssl.sh/tools/tls-config-generator/) produces a configuration that both old and new clients can use.
