kovidgoyal/kitty · error · SystemExit

Failed to compile the terminfo database

Error message

Failed to compile the terminfo database

What it means

Raised by compile_terminfo() in kitty's SSH bootstrap script when the `tic` terminfo compiler exits non-zero while compiling kitty.terminfo into a compiled terminfo database. The script captures tic's stdout/stderr, writes it to stderr for diagnosis, then aborts with SystemExit. tic is part of ncurses and must be present on the remote host during SSH shell integration bootstrap.

Source

Thrown at shell-integration/ssh/bootstrap.py:168

        try:
            os.makedirs(os.path.dirname(q))
        except EnvironmentError as e:
            if e.errno != errno.EEXIST:
                raise
        os.symlink('../x/xterm-kitty', q)
    if os.path.exists('/usr/share/misc/terminfo.cdb'):
        # NetBSD requires this
        os.symlink('../../.terminfo.cdb', os.path.join(base, tname, 'x', 'xterm-kitty'))
        tname += '.cdb'
    os.environ['TERMINFO'] = os.path.join(HOME, tname)
    p = subprocess.Popen(
        [tic, '-x', '-o', os.path.join(base, tname), os.path.join(base, '.terminfo', 'kitty.terminfo')], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
    )
    output = p.stdout.read()
    rc = p.wait()
    if rc != 0:
        getattr(sys.stderr, 'buffer', sys.stderr).write(output)
        raise SystemExit('Failed to compile the terminfo database')


def iter_base64_data(f):
    global leading_data
    started = 0
    while True:
        line = f.readline().rstrip()
        if started == 0:
            if line == b'KITTY_DATA_START':
                started = 1
            else:
                leading_data += line
        elif started == 1:
            if line == b'OK':
                started = 2
            else:
                raise SystemExit(line.decode('utf-8', 'replace').rstrip())
        else:

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Check the tic output printed just above the error — it names the exact failing capability or line
  2. Upgrade ncurses/tic on the remote host (e.g. `apt install ncurses-base ncurses-bin` or the distro equivalent)
  3. Ensure the output base directory is writable; set HOME to a writable dir before kitty ssh runs
  4. If tic is fundamentally broken on that host, copy a precompiled terminfo from a machine with matching ncurses instead of compiling

Example fix

# before
kitty +kitten ssh oldhost  # SystemExit: Failed to compile the terminfo database

# after
# on remote host:
sudo apt install ncurses-bin
# verify: tic -x -o /tmp/terminfo /usr/share/terminfo/x/kitty.terminfo && echo ok
Defensive patterns

Strategy: fallback

Validate before calling

import shutil

has_tic = shutil.which('tic') is not None
writable_home = os.access(os.path.expanduser('~'), os.W_OK)

Try / catch

try:
    compile_terminfo(...)
except SystemExit as e:
    if 'Failed to compile the terminfo' in str(e):
        # fall back to TERM=xterm or copy a precompiled terminfo
        ...

Prevention

When it happens

Trigger: SSH-ing to a host where `tic -x -o ... kitty.terminfo` fails: missing tic binary path issues produce a different error, but a non-zero tic exit (malformed terminfo source, unsupported capabilities, read-only -o output dir, old tic without -x support) triggers this.

Common situations: Remote hosts with very old ncurses/tic that reject kitty's extended capabilities; HOME or the output base dir not writable so tic can't write the database; a truncated .terminfo file after a partial transfer; odd TERM settings interfering.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/494c40c65416c784. Report an issue: GitHub.