Fix “unknown terminal type” for SSH without root
SSH dey fail with “unknown terminal type” because server no get your TERM entry. Compile terminfo into ~/.terminfo and make curses programs work without root.
Wetin “unknown terminal type” mean
If you see “unknown terminal type” error for SSH, e mean say the name inside TERM no get matching entry for terminfo database for the server. Your terminal emulator na e set that name for your laptop. The database wey suppose recognise am dey for the remote machine. When the lookup fail, every curses program for that server go stop before e draw anything, because e no get description of wetin your terminal fit do.
The fix wey go keep all the features for your emulator na one command: compile your own terminfo entry into ~/.terminfo for the server. ncurses dey search your home directory before any system directory, so you no need root and e no go change anything for other users.
TERM na name, terminfo na the database
TERM dey hold one string, and na only key that string be. terminfo na compiled database of terminal descriptions, and na the key go help program find the correct one. Description dey record how many colours the terminal get, which bytes go move cursor go row 12 column 40, which bytes F5 key dey send, and whether e fit draw underline with style. ncurses, the library wey nearly every text user interface for Linux dey build on, dey read that description when e start. Programs like top, less, nano and watch no fit paint even one screen without am.
Look your own entry:
echo "$TERM"
tput longname
infocmp -1 | head -20tput longname dey print human-readable description of anything wey TERM name. For xterm-256color e dey print:
xterm with 256 colorsinfocmp -1 dey decompile the whole entry and print one capability for each line. If both commands work, the database for this machine sabi this terminal. Na this same state you need for the other side of SSH connection too.
Wetin make e only break for SSH
SSH dey send the name and nothing else. When client request pseudo terminal, TERM dey travel with that request. OpenSSH manual talk am clearly: "the TERM environment variable is always sent whenever a pseudo-terminal is requested as it is required by the protocol". So your login shell for the VPS dey receive TERM=xterm-ghostty, or xterm-kitty, or any name wey your emulator dey use. The description behind that name dey remain for your laptop, inside your laptop database. Server wey dem build before your emulator exist never hear that name. Nothing inside the SSH connection itself dey copy terminal descriptions, and na deliberate arrangement: the protocol carry name, not capability dump.
You fit reproduce the failure for your own machine with name wey surely no dey exist:
TERM=xterm-nosuchthing tput colors
echo "$?"tput: unknown terminal "xterm-nosuchthing"The exit status na 3, wey ncurses document as unknown terminal type or missing database. Every curses program dey run the same lookup, so one missing name dey produce different message from each program, but na one cause dey behind all of dem. nano stop with Error opening terminal: xterm-nosuchthing., the standard ncurses failure when e no fit load description as e start. vim print E558: Terminal entry not found in terminfo. less print WARNING: terminal is not fully functional. Pager wey dey work halfway and editor wey refuse start fit look like unrelated bugs. Na the same missing file cause both.
Where ncurses dey find the entry
ncurses dey search for fixed order, as dem document am for terminfo(5):
$TERMINFO, if e set. E go search only that directory.$HOME/.terminfo.- Every directory wey dey listed for
$TERMINFO_DIRS. - The locations wey dem compile inside, wey for Debian and Ubuntu include
/etc/terminfo,/lib/terminfoand/usr/share/terminfo.
Run infocmp -D for the server to print the list wey that server own ncurses build dey use, instead make you trust the paths above. Step 2 na the whole trick. Your home directory dey get searched before any system directory, so one file under ~/.terminfo go fix the lookup for your account without package install and without root.
Fix 1: use TERM wey server don already know
The fastest way to unblock am na to name another terminal for one connection:
TERM=xterm-256color ssh user@203.0.113.10To make am permanent for that host, put am for ~/.ssh/config on your laptop:
Host vps1
HostName 203.0.113.10
User deploy
SetEnv TERM=xterm-256colorSetEnv need OpenSSH 7.8 or newer for the client, and dem release am for August 2018. TERM na the only variable wey no need the server permission: the manual talk say, "Similarly to SendEnv, with the exception of the TERM variable, the server must be prepared to accept the environment variable". So e go work even against hardened sshd wey no get any AcceptEnv line at all.
The cost be say: everything wey your emulator describe beyond plain xterm-256color. This include 24-bit colour wey RGB capability advertise, and styled underlines through Smulx. Programs no fit see those capabilities again, so dem go fall back to 256 colours and plain underline. The screen go work. E just no get as many capabilities as the terminal wey you choose.
No solve this by adding export TERM=xterm-256color to your .bashrc for the server. That file dey run for every connection, including connections from terminal wey the server already know, so e go downgrade sessions wey dey fine before. Keep the override for the client, where you know which emulator you dey run.
Fix 2: send your terminfo entry to the server once
Na this fix go keep your emulator as e be. Decompile the entry for your local machine, pipe am through SSH, then compile am for the other side:
infocmp -x | ssh user@203.0.113.10 -- tic -x -infocmp -x go print the entry for your current TERM as source text, including extended (user-defined) capabilities. tic -x go compile that source back into binary description for the server. The -x for both sides dey important, because without am, capabilities like Smulx go drop during transfer, and you go send a downgraded copy of your own terminal.
tic go write into the system directory when e get permission, and e go fall back to $HOME/.terminfo when the user no get write access there. Ordinary account for VPS go get the home directory, and na wetin you want. You fit also specify the destination:
infocmp -x | ssh user@203.0.113.10 -- tic -x -o '~/.terminfo' /dev/stdinThe quotes around ~/.terminfo no be decoration. ssh dey join the command words into one string and hand am to the remote shell, so if you no quote ~, your local shell go expand am first. Then you go send literal /home/yourname/.terminfo go machine where your account fit get another name. tic go fail with permission error, or e go write into path wey ncurses no dey search. Quote the tilde make the remote shell expand am.
Log in and check:
ssh user@203.0.113.10
tput longname
ls -R ~/.terminfoIf tput longname print your terminal description, e mean say the lookup don succeed. ls go show the compiled file inside subdirectory wey get the first letter of the terminal name. Then run top, or watch -n1 uptime, wey dey redraw through the same library, to confirm say real curses program fit paint the screen.
The cost na one step for each server, and the entry go dey inside one account home directory for one machine. If you rebuild the VPS, e go disappear. Put the command inside the tool wey you dey use for provisioning and managing several servers at once so new host go arrive with the entry already compiled.
Fix 3: install extended terminfo database
If you get root access and you want make the name resolve for every account for the server:
sudo apt update
sudo apt install ncurses-term
tput -T xterm-ghostty longnamencurses-term get the terminal descriptions wey base install leave out. E fix the name for root and every other user, but fix 2 no fit do this.
E only help when your terminal entry dey inside the ncurses release wey your distribution package. So check am instead of assuming. Ubuntu 24.04 ship ncurses-bin 6.4+20240113-1ubuntu2.1 (as of August 2026). Upstream add Ghostty entry for ncurses 6.5-20241228, wey newer pass am. So apt install ncurses-term for Ubuntu 24.04 no fit produce xterm-ghostty entry, no matter how many times you run am. tput -T <name> longname na the check: e print the description when the entry dey, and unknown terminal with exit status 3 when e no dey.
To install one entry system-wide instead of the complete package, copy the source over and compile am as root:
infocmp -x | ssh user@203.0.113.10 -- 'cat > /tmp/term.src'
ssh -t user@203.0.113.10 -- sudo tic -x -o /usr/share/terminfo /tmp/term.srcThe -t for the second command allocate a pseudo terminal, so sudo fit prompt for the password. Without am, sudo fit exit with sudo: no tty present and no askpass program specified.
Make emulator do the transfer
Some emulators dey ship with helper wey dey do fix 2 for you. kitty get ssh kitten: kitten ssh myserver dey connect and copy kitty's terminfo go the remote host automatically. E documentation still give the manual form, infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin, with tilde escaped for the reason wey we describe before. Ghostty document infocmp -x xterm-ghostty | ssh YOUR-SERVER -- tic -x -, and e dey ship shell integration (ssh-env and ssh-terminfo) plus +ssh action wey dey automate both fixes.
These helpers dey run the same commands wey you just run by hand. E still matter make you know the manual form, because helper no fit act when connection start from somewhere else, like for jump host or inside script.
Error come back
Under sudo -i. Root login shell get HOME=/root, and sudo dey keep your TERM. Now ncurses dey search /root/.terminfo, but that place no get your entry, so failure come back for root alone. Confirm am with sudo -i env and read the HOME and TERM lines. Install the entry for the system directory, or put one copy for /root/.terminfo.
Inside tmux or screen. Dem dey set their own TERM for programs wey dey run inside dem, commonly screen-256color or tmux-256color. Older server sabi screen-256color and fit no sabi tmux-256color, so outer shell dey okay while everything inside the session dey fail. Na the same cause, but different name. Run tput -T tmux-256color longname for the server to see which one e get. A terminal workbench wey build around tmux fit hide this until the day you attach to host wey you never fix.
On a fresh server. ~/.terminfo dey apply per account and per machine, so rebuilt VPS go start empty again.
Screen draws, keys misbehave. If display dey fine but Home, End or function keys dey insert stray characters, the name resolve to entry wey no match your terminal. Key sequences come from the same terminfo entry as the drawing capabilities, so approximate entry go give approximate keys. This na the usual result of fix 1 for emulator wey key sequences differ from xterm. Fix 2 na the answer, because na your emulator real entry get the correct sequences.
FAQ
Why I dey only see "unknown terminal type" over SSH?
Because na the database for server dey hold the entry for your terminal. Your emulator install the description for the machine where e dey run, so local programs fit find am without any extra work from you. SSH send only the value of TERM, because the protocol carry that name with the pseudo-terminal request. The remote ncurses search the remote database for the name but find nothing, so initscr fail and the program stop.
I fit fix am without root for the server?
Yes. ncurses search $HOME/.terminfo before any system directory, so entry for there enough for your account. Run infocmp -x | ssh user@host -- tic -x - once for each server. tic write inside your home directory when e no fit write to the system path, and na the normal case for unprivileged account. Log in and run tput longname to confirm say the lookup don resolve now.
Wetin I lose if I set TERM=xterm-256color for one host?
Every capability wey your emulator describe beyond the xterm-256color entry, like 24-bit colour through RGB and styled underlines through Smulx. Programs no fit see those capabilities, so dem use the closest fallback. Function-key sequences fit also different from your real terminal. Put the setting for the client inside ~/.ssh/config instead of putting am inside .bashrc for the server, because that one go downgrade sessions from terminals wey already work.
Why the error dey come back after sudo -i?
sudo -i start a login shell as root with HOME=/root, but e keep your TERM value. ncurses then search /root/.terminfo instead of your own home directory and find nothing, so root see the same failure wey your account no longer see. Run sudo -i env and check the HOME and TERM lines. Compile the entry into the system directory with sudo tic -x -o /usr/share/terminfo, or copy am into /root/.terminfo.
apt install ncurses-term always dey fix am?
No. E add only the entries wey dey inside the ncurses release your distribution package. Ubuntu 24.04 ship ncurses 6.4 (ncurses-bin 6.4+20240113-1ubuntu2.1, as of August 2026), and Ghostty's entry enter upstream for ncurses 6.5-20241228, so that package no fit contain am. Check with tput -T <name> longname before you rely on the package, and provide the entry yourself when the check still report unknown terminal.