Describe the bug
When connecting to a VM (or VMSS instance) via az serial-console connect, the console output is rendered as Python bytes repr instead of decoded text. ANSI escape sequences and CR/LF are shown as literal \x1b[0;32m, \r\n, and the entire stream is wrapped in b'...', making the serial console unusable.
The root cause is in src/serial-console/azext_serialconsole/custom.py, in the on_message callback inside SerialConsole.connect():
def on_message(_, message):
if GV.first_message:
...
else:
PC.print(message) # message can be `bytes`, gets stringified via repr()
The Azure serial console websocket endpoint sends frames that arrive as bytes from websocket-client 1.3.1 (the version vendored with the extension on Python 3.13). PC.print ultimately calls Python's built-in print() on the bytes object, which produces the b'...' repr instead of decoded text.
A one-line fix decoding the message resolves it:
def on_message(_, message):
if isinstance(message, (bytes, bytearray)):
message = bytes(message).decode("utf-8", errors="replace")
if GV.first_message:
...
else:
PC.print(message)
I patched my local install with this and the console now renders correctly with proper newlines and ANSI colors.
Related command
az serial-console connect
Errors
No exception is raised. The output looks like this (sample, sensitive parts redacted):
b'\r\n[ 2135.909432] cloud-init[3293]: The system is finally up, after 2135.90 seconds\r\n\x1b[0;32m OK \x1b[0m] Finished \x1b[0;1;39mcloud-init-final.service\x1b[0m - Cloud-init: Final Stage.\r\n...'
(every line of the boot log / login prompt is similarly wrapped)
Issue script & Debug output
export TERM=xterm-256color
az serial-console connect \
--resource-group <rg> \
--name <vmss-name> \
--instance-id <instance-id> \
--debug
The --debug log shows the websocket connection succeeds (no errors). The garbled output begins immediately after first_message is consumed and subsequent frames are forwarded to PC.print.
Expected behavior
Serial console output should be written to the terminal as decoded text so that ANSI escapes and CR/LF are interpreted by the user's terminal emulator, producing a normal cloud-init / login boot log.
Environment Summary
```
azure-cli 2.85.0
core 2.85.0
telemetry 1.1.0
Extensions:
serial-console 1.0.0b3
azure-devops 1.0.2
containerapp 1.3.0b4
databricks 1.3.1
k8s-configuration 2.3.0
k8s-extension 1.7.0
serviceconnector-passwordless 3.3.6
Python location '/opt/homebrew/Cellar/azure-cli/2.85.0/libexec/bin/python'
Python (Darwin) 3.13.12 (main, Feb 3 2026, 17:53:27) [Clang 17.0.0 (clang-1700.6.3.2)]
Installed via Homebrew on macOS 15 (Apple Silicon).
```
Vendored `websocket-client` version inside the extension: `1.3.1`.
Additional context
- Reproducible 100% of the time when connecting to any Linux VM/VMSS instance with serial console enabled.
- Workaround: monkey-patch `~/.azure/cliextensions/serial-console/azext_serialconsole/custom.py` with the `isinstance(message, bytes)` decode shown above, and delete `pycache/`.
- Likely root cause: `websocket-client` >= 1.0 returns `bytes` for binary frames (or text frames received without a UTF-8 charset hint); the extension was written assuming `str`. A version pin of `websocket-client < 1.0` would also work but is not future-proof.
- Will follow up with a PR containing the one-line fix.
Describe the bug
When connecting to a VM (or VMSS instance) via
az serial-console connect, the console output is rendered as Pythonbytesrepr instead of decoded text. ANSI escape sequences and CR/LF are shown as literal\x1b[0;32m,\r\n, and the entire stream is wrapped inb'...', making the serial console unusable.The root cause is in
src/serial-console/azext_serialconsole/custom.py, in theon_messagecallback insideSerialConsole.connect():The Azure serial console websocket endpoint sends frames that arrive as
bytesfromwebsocket-client1.3.1 (the version vendored with the extension on Python 3.13).PC.printultimately calls Python's built-inprint()on thebytesobject, which produces theb'...'repr instead of decoded text.A one-line fix decoding the message resolves it:
I patched my local install with this and the console now renders correctly with proper newlines and ANSI colors.
Related command
az serial-console connectErrors
No exception is raised. The output looks like this (sample, sensitive parts redacted):
(every line of the boot log / login prompt is similarly wrapped)
Issue script & Debug output
The
--debuglog shows the websocket connection succeeds (no errors). The garbled output begins immediately afterfirst_messageis consumed and subsequent frames are forwarded toPC.print.Expected behavior
Serial console output should be written to the terminal as decoded text so that ANSI escapes and CR/LF are interpreted by the user's terminal emulator, producing a normal cloud-init / login boot log.
Environment Summary
```
azure-cli 2.85.0
core 2.85.0
telemetry 1.1.0
Extensions:
serial-console 1.0.0b3
azure-devops 1.0.2
containerapp 1.3.0b4
databricks 1.3.1
k8s-configuration 2.3.0
k8s-extension 1.7.0
serviceconnector-passwordless 3.3.6
Python location '/opt/homebrew/Cellar/azure-cli/2.85.0/libexec/bin/python'
Python (Darwin) 3.13.12 (main, Feb 3 2026, 17:53:27) [Clang 17.0.0 (clang-1700.6.3.2)]
Installed via Homebrew on macOS 15 (Apple Silicon).
```
Vendored `websocket-client` version inside the extension: `1.3.1`.
Additional context