Azure / Azure/azure-cli-extensions

az network bastion ssh/tunnel fails with "Invalid WebSocket Header" on Azure CLI 2.76+ (Python 3.13 builds) on Windows

Open
#9,806 3 comments 0 reactions 0 assignees View on GitHub
Auto-Assign bug customer-reported Network Network - Bastion Service Attention
Dominant language
Python
Stars
454
Forks
1.7k
Avg merge
2d 19h
Merged PRs (30d)
64

Description

### Describe the bug

az network bastion ssh, az network bastion tunnel, and any other bastion extension command that establishes a WebSocket tunnel fails immediately with Exception in handling client: Invalid WebSocket Header on Windows installations of Azure CLI 2.76 and later.
The HTTP POST to /api/tokens on the Bastion host succeeds (returns 200), but the subsequent WebSocket upgrade handshake is rejected internally. The tunnel terminates before any data can be forwarded. az network bastion rdp (which downloads an .rdp file without using WebSocket tunneling) works correctly, confirming the issue is specific to the tunnel code path.

**To reproduce:**

On a Windows 11 machine with Azure CLI installed via MSI (2.76.0 through 2.85.0 — any version bundling Python 3.13):

### Related command

az network bastion ssh --name "" --resource-group "" --target-resource-id "" --auth-type "AAD" --debug

_Also happens with "ssh-key" authorization type_

### Errors

cli.azext_bastion.tunnel: Exception in handling client: Invalid WebSocket Header
cli.azext_bastion.tunnel: Cleaning up session

### Issue script & Debug output

urllib3.connectionpool: https://bst-.bastion.azure.com:443 "POST /api/tokens HTTP/1.1" 200 None
cli.azext_bastion.tunnel: Exception in handling client: Invalid WebSocket Header
cli.azext_bastion.tunnel: Cleaning up session
urllib3.connectionpool: https://bst-.bastion.azure.com:443 "DELETE /api/tokens/ HTTP/1.1" 204 0

### Expected behavior

The SSH session should open through the Bastion tunnel.

### Environment Summary

OS: Windows 11 (26200)
Azure CLI: 2.76.0, 2.84.0, 2.85.0 (MSI install) — all fail
Python (bundled): 3.13.x
bastion extension: 1.3.0, 1.4.0, 1.4.1, 1.4.2, 1.4.3 — all fail
ssh extension: 2.0.7

az version
{
"azure-cli": "2.85.0",
"azure-cli-core": "2.85.0",
"azure-cli-telemetry": "1.1.0",
"extensions": {
"bastion": "1.4.3",
"ssh": "2.0.7"
}
}

### Additional context

This a Linux VM running Ubuntu 24.04 pro. I have tried this on multiple computers and getting the same error. Oddly, the ability to ssh into the vm from my local terminal was working for me the first few days after I first setup this VM. After another user started accessing the VM is when it seems like it stopped working. I have also tried with another bastion instance on a Windows VM that we have in a different subscription, and I am getting the same error there as well (Invalid WebSocket Header), but I am still able to RDP into that Windows VM through my native client. I am also still able to access the Linux VM through Bastion in the Azure portal via ssh-key and Entra authorization.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing `az network bastion ssh` or `az network bastion tunnel` on Windows with Azure CLI 2.76+ and `--debug`, then inspect the Bastion extension's WebSocket tunnel path after the successful `/api/tokens` POST. Compare the failing handshake with the working non-WebSocket `az network bastion rdp` path. Done means SSH and tunnel sessions open and forward data without `Invalid WebSocket Header`.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, python
Domain
cli, cloud, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.