Stopping a TigerVNC Display with vncserver -kill

Before you kill anything, find out who started the display. If a systemd unit owns it, stop the unit with systemctl, or the unit and the running server stop agreeing about what's up. If you started it yourself with vncserver, run vncserver -list to see which displays are yours, then vncserver -kill :1 stops the one on :1. You never need to hunt down the process ID.

First, check whether systemd owns the display

Everything here is Debian 13 (trixie) with TigerVNC 1.15, where vncserver is an alternatives link to tigervncserver, so both names take the same options. Ubuntu, Fedora, RHEL and RealVNC Server differences are at the end.

Look for a unit before anything else. If /etc/tigervnc/vncserver.users maps the display to a user as :1=<user>, systemd started tigervncsession, Debian's name for upstream's vncsession, which opened that user's session and runs the X server. Check, stop and confirm (the unit name is Debian and Ubuntu's; Fedora and RHEL use vncserver@:1):

first, check whether systemd owns the display
systemctl list-units 'tigervncserver@*' 'vncserver@*'
sudo systemctl stop tigervncserver@:1
systemctl is-active tigervncserver@:1

If list-units comes back empty, no unit owns the display, and -kill below is the right tool. Debian 13 ships the unit as tigervncserver@.service, and once it's down is-active prints inactive.

The service runs the same wrapper in the foreground, so its display also turns up in the owner's -list, and -kill would find it. Use systemctl anyway, so the unit's state matches what's actually running.

What -kill actually does

When you start a display, the wrapper launches Xtigervnc and writes its process ID to a per-display PID file, ~/.config/tigervnc/<host>:<display#>.pid. The display number also fixes the port at 5900 plus the display number, so :1 listens on 5901. -kill :1 reads that PID file and signals the process for you.

It sends TERM first, waits about a second, and falls back to SIGKILL if the server hangs. Then it removes the PID file and the /tmp/.X1-lock and /tmp/.X11-unix/X1 locks, so you can start :1 again straight away.

Sessions from x0vncserver are wrapper sessions too, and -kill handles them the same way. That server shares an X display that already exists instead of creating one, so killing it ends the sharing and leaves the desktop running.

Command What it does Notes
vncserver -list Lists the sessions you started with the wrapper One row per display: display, RFB port, PID, server. A dead one shows (stale)
vncserver -kill :1 Stops display :1 The one you’ll use nearly every time
vncserver -kill Stops your only session Refuses when you have more than one
vncserver -kill :* Stops all your local sessions Add -dry-run first: it prints the Killing ... line for each display it would hit, then stops there
vncserver -kill :1 -clean Stops :1 and deletes its log Leave -clean off if you still need the log to debug a crash
vncserver -list -cleanstale Removes stale PID files and X11 locks For a server that crashed instead of being killed

Kill display :1 and check it's gone

Do this as the user who owns the session. The wrapper only reads that user's PID files, so root running -list won't see another account's displays.

kill display :1 and check it’s gone
vncserver -list

You get one row per display:

kill display :1 and check it’s gone
TigerVNC server sessions:

X DISPLAY #   RFB PORT #   RFB UNIX PATH   PROCESS ID #   SERVER
1             5901                         <pid>          Xtigervnc

Then kill it by number:

kill display :1 and check it’s gone
vncserver -kill :1

It answers Killing Xtigervnc process ID <pid>... success!. Now check that the display and the port are both gone:

kill display :1 and check it’s gone
vncserver -list
ss -ltn 'sport = :5901'

:1 has dropped out of the list, and ss prints only its header line because nothing listens on 5901 any more.

When -kill doesn't do what you expect

A person at a laptop marking a session row while a rack unit and small monitor connect via a thin line.

  • -list shows <pid> (stale): the server died without cleaning up, usually a crash. Run vncserver -list -cleanstale; it removes the stale PID files and the X11 locks in /tmp, and the next -list comes back clean.
  • No matching VNC server running for this user!: there's no PID file for that display under your account. You're the wrong user, a systemd unit owns the display, or someone started Xvnc by hand. Run the systemctl list-units check from the section above, then look for the process.
  • This is ambiguous. Multiple VNC servers are running for this user!: you ran a bare -kill with more than one session up. The wrapper prints the session table along with the error; pick the display and run vncserver -kill :1.
  • ... which seems to be deadlocked. Using SIGKILL!: the server ignored TERM for a second and the wrapper killed it hard. Confirm with vncserver -list and ss -ltn 'sport = :5901'.
  • Desktop programs such as xterm keep running after the kill: they came from the session's startup script and outlived the X server. Find them with pgrep -a -u <user> and end them the way the next section shows.

No PID file, or a server started with Xvnc directly

Find the server by its full command line and signal it yourself:

no pid file, or a server started with xvnc directly
pgrep -a -f 'vnc :1( |$)'
kill <pid>
kill -s KILL <pid>

pgrep -a -f matches the full command line and prints it next to the PID, for example /usr/bin/Xtigervnc :1 .... You need -f because plain name matching stops at 15 characters. Make sure it's your display before you signal it. kill sends TERM by default, which gives the server its chance to clean up; send KILL only if the process is still there after that.

Ubuntu 24.04, Fedora, RHEL and RealVNC Server

  • Ubuntu 24.04 uses the same Debian wrapper and ships the same tigervncserver@.service unit, but with TigerVNC 1.13.1. The commands and messages match; the PID files and logs live in ~/.vnc/ instead of ~/.config/tigervnc/.
  • Fedora and RHEL name the unit vncserver@:<display>, so a service display stops with sudo systemctl stop vncserver@:1.
  • Fedora installs /usr/bin/vncserver as a legacy script that behaves differently from the Debian wrapper:
    • every run prints a deprecation warning, and its files live in ~/.vnc/;
    • -list shows only X DISPLAY # and PROCESS ID, silently drops dead entries, and has no -cleanstale;
    • -kill sends TERM once; a hung Xvnc gets Xvnc seems to be deadlocked, the SIGKILL is yours to send, and a second vncserver -kill :1 then cleans up the sockets;
    • with no PID file it stops at Can't find file and tells you to kill Xvnc manually;
    • the process is named Xvnc, which the pgrep pattern above also matches.
  • RHEL treats the systemd service as the way to run VNC, with users mapped in /etc/tigervnc/vncserver.users. From TigerVNC 1.14 on, configuration sits under $HOME/.config/tigervnc and logs under $HOME/.local/state/tigervnc.
  • RealVNC Server has its own commands. A Virtual Mode desktop ends with vncserver-virtual -kill :1, and the Service Mode server is a systemd unit, so it stops with sudo systemctl stop vncserver-x11-serviced.

After a restart, check what it listens on

Start the display again and look at the listener:

after a restart, check what it listens on
vncserver :1
ss -ltn 'sport = :5901'

A plain restart shows 127.0.0.1:5901, so the display is reachable only through an SSH tunnel. The wrapper listens on localhost only unless you pass -localhost no or your security types include a TLS or X509 type and no *None type. For a direct connection, start it with vncserver :1 -localhost no, and ss shows the port on all addresses instead. That start offers VncAuth,TLSVnc, and the viewer picks the type from that list, so it can still take plain VNC auth; add -SecurityTypes TLSVnc when the port crosses a network you don't control.

If a setting doesn't stick, look in /etc/tigervnc/vncserver-config-mandatory. Options there override both your config and the command line, so a localhost line in that file beats your -localhost no.

A display that should come back after every reboot belongs to systemd: map it as :1=<user> in /etc/tigervnc/vncserver.users and run sudo systemctl enable --now tigervncserver@:1. Keep vncserver and -kill for the sessions you start for one job and tear down yourself.

FAQs

Does TigerVNC end a virtual desktop when its window-manager session exits?

With the Debian wrapper, yes. -autokill is on by default, so the server stops when Xtigervnc-session exits, which in most cases means when you log out of the window manager. Start the display with vncserver :1 -autokill no if you want it to outlive the logout.

Can I stop a display on another machine?

Yes. Give the Debian wrapper a host and it uses SSH to kill the server there: vncserver -kill <user>@<server-host>:1.

Can a display stop by itself when the one application in it closes?

Yes. Make that application the startup program with -xstartup, and the default -autokill stops the server as soon as it exits:

can a display stop by itself when the one application in it
vncserver :1 -xstartup /usr/bin/xterm

Close the xterm and :1 drops out of vncserver -list. The program has to stay in the foreground. One that forks into the background and returns within three seconds takes the display straight down, and the wrapper prints cleanly exited too early (< 3 seconds)!.