Skip to main content
RunBook Academy

Proxmox VEIX · Virtual MachinesGuest integration

Consoles and recovery: noVNC, SPICE, serial and qm terminal

Advanced⏱ ~24 min🧪 Lab requiredqm

What you'll learn

  • Choose between noVNC, SPICE, a serial console and the QEMU monitor for a given failure
  • Configure a serial console on the PVE side and inside a Linux guest so it survives a broken boot
  • Recover a guest that will not boot, from the console, without restoring it
  • Explain what the QEMU monitor can do that no in-guest tool can

Prerequisites

Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12

Not yet marked complete on this device.

Every guest you administer over SSH has a failure mode where SSH is exactly what stopped working: a firewall rule applied without a rollback timer, a network configuration that did not survive a reboot, a full root filesystem, a service that fails and takes sshd with it, a kernel that panics before userspace starts.

The console is the answer, and Proxmox offers four of them with genuinely different reach. Choosing between them under pressure requires knowing which ones survive which failures — and one of them has to be configured in advance or it is not there when you need it.

Four consoles, and what each survives

ConsoleReachesSurvives a broken networkShows the boot processNeeds guest configuration
noVNCThe emulated graphics adapterYesYes, if the guest writes to VGANo
SPICEThe same, with a richer protocolYesYesA client (virt-viewer) on your workstation
Serial (qm terminal)A virtual serial portYesOnly if configured on both sidesYes
QEMU monitor (qm monitor)The hypervisor, not the guestYesNot applicable — it is below the guestNo

The distinction that matters is the last column against the third. noVNC works with no preparation and is therefore what everyone reaches for. A serial console requires setting up in advance and gives you things noVNC cannot: a scrollback buffer, copy and paste that works, text you can search, a kernel log that keeps flowing when the graphics stack is broken, and a session you can drive from a script.

noVNC and SPICE

noVNC is the default and needs nothing. It renders the emulated display in a browser and is the correct tool for a graphical installer, a Windows guest, or any situation where you want to see what a screen would show.

Its limitations are real and are the reason this lesson continues:

  • It is a picture. There is no text to copy. A stack trace has to be transcribed by hand or photographed.
  • There is no scrollback. A kernel panic that scrolls past is gone.
  • Keyboard layout is a recurring problem. A guest expecting one layout and a browser sending another produces mistyped passwords that look like authentication failures.
  • It shows nothing if the guest has stopped writing to the display, which is exactly what a guest configured for serial-only output does.

SPICE improves the interactive experience — better performance, clipboard integration, USB redirection, multiple monitors — at the cost of needing a client installed locally. It is worth configuring for desktop-style guests and is not a recovery tool in any way noVNC is not.

Configuration changedisplay type
set -euo pipefail
VMID=118

qm set "$VMID" --vga qxl        # SPICE
qm set "$VMID" --vga std        # plain VGA for noVNC
qm set "$VMID" --vga serial0    # redirect the web console to serial port 0

The serial console, done properly

Two halves, and the whole value depends on both being present.

Configuration changehost side: add a serial port
set -euo pipefail
VMID=118

qm set "$VMID" --serial0 socket

qm shutdown "$VMID" --timeout 300
qm start "$VMID"

The serial[n] option accepts either a host device path or the literal socket. Passing through a real /dev/ttyS0 is for hardware scenarios; socket is what you want for a guest console, and the documentation is explicit that qm terminal is how you open a connection to it.

Configuration changeguest side, Linux: kernel output plus a login prompt
set -euo pipefail

# 1. Kernel and bootloader output on the serial line.
sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="\(.*\)"/GRUB_CMDLINE_LINUX_DEFAULT="\1 console=tty0 console=ttyS0,115200n8"/' \
/etc/default/grub

# 2. GRUB itself on the serial line, so you can pick a rescue kernel.
cat >> /etc/default/grub <<'EOF'
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
EOF

update-grub

# 3. A login prompt on ttyS0 once userspace is up.
systemctl enable --now serial-getty@ttyS0.service

The order of the two console= parameters matters: the last one named becomes /dev/console, which is where the init system and early userspace send output. Listing tty0 first and ttyS0 second gives you kernel messages on both and the primary console on serial, which is the arrangement you want for a headless guest.

Read-only / Safeconnecting
# qm terminal 118
starting serial terminal on interface serial0 (press Ctrl+O to exit)

app-frontend-01 login:

Illustrative output

Recovering a guest that will not boot

The sequence below is ordered by cost. Each step preserves more evidence than the one after it.

Read-only / Safe1. Establish what state the guest is actually in
set -euo pipefail
VMID=118

qm status "$VMID" --verbose
qm config "$VMID"

# A lock left by an interrupted operation blocks everything else.
qm config "$VMID" | grep -E '^lock:' && echo 'VM is locked; find out why before clearing'

# If the agent is configured, is the guest frozen rather than hung?
qm guest cmd "$VMID" fsfreeze-status 2>/dev/null || true
Service impact possible2. Boot into a rescue target from the guest bootloader
set -euo pipefail
VMID=118

# Attach to the console BEFORE starting, so you catch the bootloader.
# In one terminal:
#   qm terminal $VMID
# In another:
qm start "$VMID"

# At the GRUB menu: press 'e', append to the linux line, then Ctrl-X.
#   systemd.unit=rescue.target       single-user with the root filesystem
#   systemd.unit=emergency.target    minimal, root mounted read-only
#   init=/bin/bash                   no init at all, last resort
#
# In emergency mode the root filesystem is read-only. Remount it before
# editing anything:
#   mount -o remount,rw /

The Linux course covers what to do once you are there in emergency and rescue modes and boot failure diagnosis. The Proxmox-specific part is only how to get a console that shows you the bootloader, which is what the first half of this lesson was about.

Data-loss risk3. Mount the guest disk from the host, when the guest cannot boot at all
set -euo pipefail
VMID=118

# Absolutely first: confirm it is stopped.
qm status "$VMID" | grep -q 'status: stopped' || { echo 'VM is not stopped'; exit 1; }

# For a ZFS-backed disk, the zvol has partition device nodes already.
ls -l /dev/zvol/rpool/data/vm-"$VMID"-disk-0*
mkdir -p /mnt/rescue
mount /dev/zvol/rpool/data/vm-"$VMID"-disk-0-part1 /mnt/rescue

# For a qcow2 or raw file on directory storage, use libguestfs rather than
# a loop device: it handles LVM and multiple partitions and does not require
# the host kernel to trust the guest filesystem.
#   apt install -y libguestfs-tools
#   guestmount -a /var/lib/vz/images/118/vm-118-disk-0.qcow2 -i --ro /mnt/rescue

# Fix, then unmount before starting the VM again.
umount /mnt/rescue

Knowledge check

Knowledge check · 4 questions

  1. Q1. The cluster web interface is down and a guest needs to be recovered. You have SSH to the node. Which console is available?

  2. Q2. What does a properly configured serial console give you that noVNC does not? Select all that apply.

  3. Q3. Setting the display type to serial0 is a safe change to make in advance, because the graphical console remains available as a fallback.

  4. Q4. A guest will not boot and you decide to mount its disk from the PVE host to repair a broken /etc/fstab. What is the most important precaution?

Passing score: 75%. Answers are checked in this browser.