Linux Error Messages Dictionary: Common Errors, Causes, and Fixes

Linux Error Messages Dictionary: Common Errors, Causes, and Fixes

How to Use This Dictionary

Each heading is the literal error string. Press Ctrl+F, search for the text shown in your terminal, then read the "Cause", "Diagnose", and "Fix" of the matching section top to bottom for the fastest recovery.

Universal rules

  • Read the first line of the error, not just the last (the root cause is usually printed first)
  • Don't add sudo on a guess. Diagnose the cause first
  • Always isolate three things in order: which command / which file / which permission

Assumptions (target environment)

  • OS: common distributions (Ubuntu / Debian / RHEL family)
  • Shell: bash (zsh behaves the same for most cases)
  • Operating as a regular user

What does "command not found" mean?

The shell cannot locate an executable with that name on PATH. The cause is almost always a typo, a missing package, or a misconfigured PATH.

bash: dokcer: command not found

Diagnose:

command -v docker      # prints the real path if it is on PATH
which docker           # same idea (external command)
echo "$PATH"           # is the expected directory included?
type docker            # alias / function / real binary?

Fix:

  • Typo: the example above is dokcer; the correct name is docker
  • Not installed: sudo apt install <package> (RHEL family: dnf install)
  • Missing PATH: binary exists but is not found. Add export PATH="$PATH:/usr/local/bin" to ~/.bashrc
  • Only fails under sudo: sudo uses secure_path, a different PATH. Use a full path or sudo env "PATH=$PATH" cmd

If "not found" persists right after installing, the shell has cached the command location. Clear it with hash -r.

See Fixing "command not found" Errors for details.

Why does "Permission denied" appear?

The running user lacks the required permission (read/write/execute) on the target. The cause is file permissions, ownership, a missing directory execute bit, or SELinux/AppArmor.

bash: ./deploy.sh: Permission denied
-bash: /var/log/app.log: Permission denied

Diagnose:

ls -l deploy.sh        # is the execute bit set? who owns it?
ls -ld /var/log        # parent directory permissions
whoami                 # your username
id                     # your groups

Fix:

  • Script won't run: chmod +x deploy.sh
  • Cannot write the file: if you own it, chmod u+w file; if owned by someone else, use sudo or sudo chown $USER file
  • Cannot enter a directory: a directory needs the execute bit x. chmod +x dir
  • System-owned areas (/etc, /var/log): make configuration changes via sudo

Slapping chmod 777 on things to "just make it work" causes incidents. Stay with least privilege (files 644/755, directories 755).

See Permission Denied Fix for details.

The real meaning of "No such file or directory"

The path does not exist, or an intermediate directory is missing. It also appears with broken symlinks, misread relative paths, and a wrong interpreter line (shebang).

cat: config.yml: No such file or directory
bash: ./run.sh: /bin/bash^M: bad interpreter: No such file or directory

Diagnose:

pwd                    # where am I now?
ls -la                 # does the file really exist (including hidden)?
file run.sh            # check for CRLF line endings
readlink -f link       # final target of a symlink

Fix:

  • Misread relative path: if cat ./config.yml fails, check the absolute path cat /etc/app/config.yml
  • "not found" on shebang: a trailing ^M means Windows (CRLF) line endings. Strip them: sed -i 's/\r$//' run.sh
  • Wrong shebang path: #!/bin/bash vs /usr/bin/bash. Confirm the real path with which bash
  • Broken symlink: if ls -l shows the target in red, the destination is gone. Recreate the link

How to investigate "No space left on device"

The target filesystem has no free space. The pitfall: the same message appears on inode exhaustion (huge numbers of tiny files), not just on running out of data blocks.

cp: error writing 'backup.tar': No space left on device

Diagnose:

df -h                  # space usage (Use%)
df -i                  # inode usage (IUse%) <- easy to overlook
du -sh /var/* 2>/dev/null | sort -h   # what is large?

Fix:

  • Block exhaustion: delete huge logs and old archives. Compact logs with journalctl --vacuum-size=200M
  • Inode exhaustion: if df -i shows 100%, you cannot write even with free space. Remove unneeded small files (caches, sessions)
  • Deleted but space not reclaimed: a process still holds the file. Find it with lsof +L1 and restart that process

Even right after rm, space is not freed while a process still has the file open. df will not drop until the service restarts.

See Investigating "No Space Left on Device" for details.

"Connection refused" vs "timed out"

Connection refused means the packet reached the host but the port rejected it (service down or wrong port). Connection timed out means no response came back (route, firewall, or host down). This distinction is the starting point of diagnosis.

ssh: connect to host 10.0.0.5 port 22: Connection refused
curl: (28) Failed to connect to api.example.com port 443: Connection timed out

Diagnose:

ping -c3 10.0.0.5                    # is the host reachable?
nc -vz 10.0.0.5 22                   # is the port open?
ss -tlnp | grep :22                  # is the service LISTENing on the server?

Fix:

  • refused: confirm the service is running, systemctl status sshd. Also check for a wrong port number
  • timed out: check firewall/security group rules, the route (traceroute), and whether the host is alive
  • name resolution fails: Could not resolve host is a DNS problem. Check /etc/resolv.conf and getent hosts <name>

See SSH Connection Troubleshooting and Network Commands Basics for details.

Fixing "Address already in use"

The port your process wants is already held by another process. Common causes: a leftover process from a previous run, double-start, or a lingering TIME_WAIT socket.

Error: listen EADDRINUSE: address already in use :::3000
bind: Address already in use

Diagnose:

ss -tlnp | grep :3000      # which PID holds the port
lsof -i :3000              # same, with process name

Fix:

  • Stop the leftover process: kill <PID>; if it ignores you, kill -9 <PID>
  • Double-start: check whether systemd or a process manager (pm2, etc.) started it more than once
  • Cannot rebind due to TIME_WAIT: enable SO_REUSEADDR in the app, or wait a few dozen seconds

When you see "Killed" / Out of memory

Most Killed messages come from the OOM killer terminating a process under memory pressure. Even when the app log has no trace, the kernel log records it.

$ ./train.py
Killed

Diagnose:

dmesg -T | grep -i -E 'oom|killed process'   # OOM evidence
journalctl -k | grep -i oom                  # systemd environment
free -h                                       # current memory / swap

Fix:

  • Out of physical memory: reduce batch size, stop unneeded processes, add swap
  • One process bloated: find the memory hog with ps aux --sort=-%mem | head
  • Container limit: check whether you hit the --memory limit and revise it

A Killed without OOM may be a manual kill or a timeout killer. If dmesg has no OOM record, suspect those instead.

bad interpreter / Exec format error

The kernel cannot launch the executable. The cause is a wrong shebang, CRLF contamination, or an architecture mismatch (e.g. running an ARM binary on x86).

./run.sh: /bin/sh^M: bad interpreter: No such file or directory
./app: cannot execute binary file: Exec format error

Diagnose:

head -1 run.sh         # eyeball the shebang line
file app               # binary architecture (x86-64 / ARM aarch64)
uname -m               # architecture of the running host

Fix:

  • Trailing ^M: strip CRLF, sed -i 's/\r$//' run.sh
  • Wrong shebang path: confirm the real path with which and fix it
  • Architecture mismatch: rebuild for that host; for cross-execution consider qemu-user

First moves on "segmentation fault (core dumped)"

The process accessed invalid memory and the OS terminated it. Usually an application bug, but a corrupted shared library or version mismatch can also cause it.

Segmentation fault (core dumped)

Diagnose:

dmesg -T | tail                       # the segfault address
ldd /path/to/app                      # shared library resolution (any "not found"?)
ulimit -c                             # is core dump generation allowed?

Fix:

  • Library mismatch: if ldd shows not found, reinstall that library
  • Reproducible bug: run with ulimit -c unlimited, then gdb <app> <core> and get bt (backtrace)
  • Right after an update: verify dependency consistency (apt install --reinstall <pkg>)

See Package Management Basics for details.

Error Cheat Sheet

Message Main cause First command
command not found not installed / PATH command -v cmd
Permission denied permission / owner ls -l target
No such file or directory wrong path / CRLF ls -la / file f
No space left on device space / inode exhaustion df -h / df -i
Connection refused service down ss -tlnp
Connection timed out route / firewall nc -vz host port
Address already in use port in use lsof -i :PORT
Killed OOM dmesg -T | grep -i oom
Exec format error arch mismatch file app
Segmentation fault app / library ldd app

What not to do

  • Adding sudo without reading the message
  • Burying permission problems under chmod 777
  • Checking only df and never df -i (inodes)
  • Judging Killed from the app log alone (never checking the kernel log)

Next Reading