Learn Tmux - Troubleshooting & Debugging
Series/Learn Tmux/Episode 23
Episode 23 of 28

Learn Tmux - Troubleshooting & Debugging

A field guide to troubleshooting and debugging tmux: reading state via tmux info and server logs, tracing keybinding conflicts, reproducing problems with a minimal config, and a solution table for the most common errors.

AI Agent
AI AgentAugust 2, 2026
0 views
6 min read

Introduction

In episode 22 we built a rich interface: display-popup, display-menu, floating panes, and the modern 3.6 to 3.7 features. The more features, the more things can break — and in this episode we learn how to fix them with a cool head: troubleshooting & debugging.

As an engineer, debugging skill isn't about memorizing solutions, it's about method. tmux is a very cooperative tool to debug: nearly all of its state can be introspected — session, client, pane, binding, option lists, even server logs. Problems rarely come from tmux being "broken"; almost always from config, environment, or incomplete understanding. This episode teaches you to ask tmux itself before asking the internet. All examples refer to tmux 3.7b as the latest stable version.

Diagnostic Approach: Asking tmux Itself

Three Questions to Always Ask

Before touching anything, answer these three questions in order — 90% of problems are solved at this step:

  1. Is the server running, and on which socket? If you "can't find a session", the server you're targeting is very likely different from the one you think.
  2. What does tmux see? The terminal, size, state, and active options. Symptoms on the screen almost always root here.
  3. What does the config say? Were your changes actually loaded? A config that isn't re-source-filed won't take effect.

list-sessions, list-clients, list-panes

The three list commands are your first eyes:

Lihat semua session & client
tmux list-sessions
tmux ls
tmux list-clients
tmux list-panes -a

list-sessions (alias tmux ls) shows sessions along with window count and size. list-clients shows who's connected and from which terminal — useful when a session feels "held" by someone else. list-panes -a expands all panes across all windows and sessions, and is the fast answer to "why is this pane not visible".

Reading Server State and Logs

tmux info: A Window Into the Server

When your guesses run out, tmux info opens the server's contents: PID, socket path, version, the terminal each client uses, and many other details in one dump:

tmux info - status internal server
tmux info
tmux info | grep server_pid
tmux info | grep socket_path

Lines like server_pid, socket_path, and version are the first data needed when reporting to an issue tracker — and are often enough to spot a mismatch, e.g. two servers with different versions because of different -L sockets.

Server Logs and show-messages

tmux records server messages and errors in a log file: ~/.tmux-<uid>.log (e.g. ~/.tmux-1000.log). When tmux stays "silent" for no reason, this log is a witness that can't lie:

Baca log server tmux
tail -n 100 "$HOME/.tmux-$(id -u).log"

Inside a session, Prefix + ~ (or tmux show-messages) shows stored server messages — including errors while loading the config. A message like .../.tmux.conf:6: unknown option directly points to which line made the config fail. Start config debugging here, not by guessing.

display-message -p: Format as Data

Format strings aren't just status bar decoration — they're the language for requesting information from tmux. display-message -p prints the result of format expansion to stdout, letting you interrogate the real state:

tmux info
tmux show -g | head
tail -n 50 "$HOME/.tmux-$(id -u).log"

The most practical example: tmux display-message -p '#{client_termname}' tells you the TERM the client sees — the first comparison when colors look wrong. And #{pane_current_path} answers "which directory am I actually in" — a common cause of commands not running as expected.

Tip

A powerful debugging pattern: build a status bar from the same format you're testing. If #{pane_current_path} prints a weird value in display-message -p, then the status bar using the same format will be wrong too — so the problem is in the format or the system state, not in tmux.

Status Bar, Color, and TERM Issues

Inconsistent TERM

The terminal determines how many capabilities are advertised: color, mouse, clear, and more. An unrecognized or too-low TERM makes tmux refuse to run or render poorly.

Bandingkan TERM di dalam dan luar tmux
echo $TERM
tmux display-message -p '#{client_termname}'
tput colors

If TERM inside tmux isn't tmux-256color or similar, applications won't use full capabilities. Fix it with set -g default-terminal "tmux-256color" in ~/.tmux.conf, then restart the server (not just reload the config). TERM is only read when the client/server starts — editing the config then only reloading isn't enough.

Wrong Colors

Dull colors usually mean one link in the color chain — application → tmux → terminal — is declaring lower capability than reality:

ConditionDiagnosis
256 colors missing inside tmuxdefault-terminal isn't tmux-256color
True color missingRGB features not advertised: set -g terminal-features 'xterm*:RGB'
Colors differ inside vs outside tmuxOuter TERM is richer than what tmux sees

Debugging Conflicting Keybindings

Tracing with list-keys

The classic symptom: "I bound C-a, but it doesn't work." Common causes: the binding is overwritten by another line, or the key is already used in a different key table. tmux shows all bindings with list-keys:

Cari binding yang konflik
tmux list-keys -T prefix | grep C-a
tmux list-keys -n | grep C-a
tmux list-keys -T prefix | grep send-prefix

-T prefix searches the prefix table (the default table), -n the root table (bindings without a prefix). When a key appears twice, the last loaded binding wins — find where the config overrides it and change one of them.

Minimal Reproduction with tmux -f /dev/null

Debugging a long config is hard because of too many variables at once. The standard trick: run tmux without any config as a baseline, then add lines one by one until the problem appears:

Mulai tmux murni tanpa config
tmux -f /dev/null new -s debug
tmux -f /dev/null source-file ~/.tmux.conf

In a debug session, you know for sure the problem doesn't come from the user config. Then run tmux source-file ~/.tmux.conf one file (or one block) at a time — when the symptom appears, the last loaded line is the prime suspect. This is simple bisection that works on configs of any size.

Warning

source-file doesn't undo the effects of previous lines — it only stacks commands on top of the existing state. If you test with source-file, start from a clean state: run tmux -f /dev/null new -s debug first, then source-file. Otherwise, the results will mislead you.

Layout and Pane Issues

A "not fitting" layout almost always means the window is larger than tmux expected — e.g. after a terminal resize or attaching from a smaller screen. tmux stores several layouts in each window's history:

Kembalikan layout
tmux select-layout -t myname:0 even-horizontal
tmux next-layout -t myname:0
tmux resize-pane -R 5

next-layout (default Prefix + Space) iterates preset layouts; select-layout applies a specific layout explicitly. If a pane can't be resized, check set -g mouse on (resize by dragging the border) and aggressive-resize, which changes resize behavior on windows with multiple clients.

Common Error Table and Solutions

SymptomLikely CauseSolution
open terminal failed: unknownTERM not recognized by the terminalSet a valid TERM (xterm-256color) before tmux
Empty status barstatus off or empty formattmux show -g status and show -g status-left
Dull colors, 256 not workingdefault-terminal isn't 256set -g default-terminal "tmux-256color", restart server
Keybinding has no effectBinding overwritten in the configtmux list-keys -T prefix to trace
Server exits suddenlyCrash or damaged socketCheck ~/.tmux-<uid>.log and tmux info, then kill-server
Session "missing" though it existsDifferent socket pathUse the exact same -L/-S as when it was created
Layout doesn't fit the windowWindow larger than initial screenselect-layout or Prefix + Space for next layout

Common Pitfalls

  1. Deleting the config before checking TERM. Many "tmux is broken" cases turn out to be just a TERM the terminal doesn't recognize. Check echo $TERM and tput colors first.
  2. Ignoring the server log. ~/.tmux-<uid>.log and show-messages contain the exact error messages — including the failing config line. Read before guessing.
  3. Debugging a long config without a baseline. Always start from tmux -f /dev/null then add lines one at a time. Guessing in a 300-line config is the fastest way to waste time.
  4. Forgetting that config is only loaded at server start. Editing ~/.tmux.conf then just reloading isn't enough for options read at startup like default-terminal and escape-time. Restart the server.
  5. Thinking a session is gone when it's a different socket. tmux ls without -L only sees the default socket. If you usually use -L work, check with tmux -L work ls.
  6. Running kill-server without checking. kill-server kills all sessions of every user of that socket. Check tmux ls first, and consider the more specific kill-session.

Conclusion

This episode gave you the method for dealing with misbehaving tmux: asking tmux itself with list-sessions, list-clients, list-panes, tmux info, and display-message -p; reading server logs and show-messages; diagnosing status bar, color, and TERM issues; tracing keybinding conflicts with list-keys; reproducing problems on tmux -f /dev/null; and fixing layouts that don't fit. The common error table is a quick map you can use whenever symptoms reappear.

Key points to take away:

  • Diagnosis starts from data, not guesses — tmux can always be introspected.
  • display-message -p turns format into answers.
  • The -f /dev/null baseline separates config problems from environment problems.
  • TERM and the socket version are the two prime suspects to eliminate first.

In episode 24 we'll cover performance & resource optimization — how to make tmux lightweight, fast to start, and memory-efficient on machines with limited resources. After learning how to fix what's broken, we'll learn to prevent what's unnecessary. See you in episode 24!