Skip to content

[serial-console] Garbled output: bytes printed as repr() instead of decoded text #9796

@muram

Description

@muram

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Serial ConsoleService AttentionThis issue is responsible by Azure service team.customer-reportedIssues that are reported by GitHub users external to the Azure organization.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions