Common Linux Errors and How to Fix Them🔧
A no-fluff guide to common Linux errors, why they happen, and how to fix them—with real-world examples and commands that actually work.
"What are some common Linux errors and how do you fix them?"
Someone hit me with that question yesterday, and it stuck. It’s not the flashiest topic—but it’s one every Linux user needs to get comfortable with.
So I put together this unofficial field guide: real-world Linux errors, why they happen, and exactly how to fix them. No fluff—just straight-up commands, logic, and the mindset to troubleshoot like a pro.
🔧 Common Linux Errors and Fixes
1. "Permission denied"
Cause: Attempting to access or execute something without proper permissions.
You download or write a shell script and try to execute it:
./backup.sh
🔻 Output:
bash: ./backup.sh: Permission denied
🔍 Why It Happens:
The script file doesn’t have the execute permission for your user. Linux is strict about execution rights—just because you own the file doesn't mean you can run it.
✅ Fix:
- Check permissions:
ls -l backup.sh
Output:
-rw-r--r-- 1 bryan bryan 0 Mar 29 14:31 backup.sh
- Add execute permission:
chmod +x backup.sh
Now when you check permissions again with ls -l
:
bryan@myPi:~/testDir $ ls -l backup.sh
-rwxr-xr-x 1 bryan bryan 0 Mar 29 14:31 backup.sh
- Try running it again:
./backup.sh
It Works!
You may need to change ownership, username : group
In that case:
ls -l backup.sh
-rwxr-xr-x 1 root root 0 Mar 29 10:02 backup.sh
sudo chown bryan:bryan backup.sh
ls -l backup.sh
-rwxr-xr-x 1 bryan bryan 0 Mar 29 10:31 backup.sh
2. "Command not found"
Cause: The command isn't installed or not in your $PATH
.
Example:
bryan@myPi:~ $ wget -O myfile.txt https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.2.27/arch/arm/configs/bcmrpi_defconfig
-bash: wget: command not found
✅ Fix:
# Check for typos, then install:
sudo apt install <package> # Debian/Ubuntu
sudo dnf install <package> # RHEL/CentOS/Fedora
# Or add to PATH:
export PATH=$PATH:/custom/bin
bryan@myPi:~ $ sudo apt install wget
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
brave-keyring hplip-data libfltk1.3 libhpmud0 libsane-hpaio printer-driver-hpcups printer-driver-postscript-hp python3-renderpm python3-reportlab python3-reportlab-accel
Use 'sudo apt autoremove' to remove them.
The following NEW packages will be installed:
wget
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
3. "No space left on device"
Cause: Disk or inode usage is maxed out.
✅ Fix:
df -h # Check disk space
df -i # Check inodes
# Cleanup:
sudo journalctl --vacuum-time=7d
sudo rm -rf /tmp/*
Example:
bryan@myPi:~ $ df -h
Filesystem Size Used Avail Use% Mounted on
udev 3.9G 0 3.9G 0% /dev
tmpfs 807M 5.8M 801M 1% /run
/dev/mmcblk0p2 57G 54G 0 100% /
/dev/mmcblk0p2 is 100% in Use
bryan@myPi:~ $ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 255440 491 254949 1% /dev
tmpfs 258052 873 257179 1% /run
/dev/mmcblk0p2 3784704 240504 3544200 7% /
tmpfs 258052 9 258043 1% /dev/shm
tmpfs 258052 5 258047 1% /run/lock
/dev/mmcblk0p1 0 0 0 - /boot/firmware
tmpfs 206440 67 206373 1% /run/user/106
tmpfs 206440 60 206380 1% /run/user/1000
No issues seen here in this instance regarding inodes
📦 What are inodes?
In Linux (and UNIX-like systems), an inode is a data structure in file systems that store metadata about files and directories, like size, permissions, and timestamps, but not the file's name or actual data content.
It’s short for "index node".
bryan@myPi:~ $ sudo journalctl --vacuum-time=7d
Vacuuming done, freed 0B of archived journals from /run/log/journal.
Vacuuming done, freed 0B of archived journals from /var/log/journal/1b12da273e8f40848d667f077b822d19.
Vacuuming done, freed 0B of archived journals from /var/log/journal.
Delete all journal logs older than 7 days.
bryan@myPi:~ $ sudo rm -rf /tmp/*
Deletes everything inside /tmp
but not the directory itself.
4. "Network is unreachable"
Cause: Bad IP config, missing route, or DNS failure.
This one could be a whole post on its own, depending on your Linux distribution and init system, but in simplest terms, for my setup:
✅ Fix:
# Check interfaces
bryan@myPi:~ $ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 172.16.12.100/25 brd 172.16.12.127 scope global dynamic noprefixroute wlan0
valid_lft 56876sec preferred_lft 56876sec
inet6 xx:xx:xx:xx:xx:xx/64 scope global dynamic noprefixroute
valid_lft 1800sec preferred_lft 1800sec
inet6 fe80::4bfb:8a88:a1bb:ccbd/64 scope link noprefixroute
valid_lft forever preferred_lft forever
# Check routes
bryan@myPi:~ $ ip r
default via 172.16.12.1 dev wlan0 proto dhcp src 172.16.12.100 metric 600
172.16.12.0/25 dev wlan0 proto kernel scope link src 172.16.12.100 metric 600
# Test raw connectivity
bryan@myPi:~ $ ping 96.7.128.175
PING 96.7.128.175 (96.7.128.175) 56(84) bytes of data.
64 bytes from 96.7.128.175: icmp_seq=1 ttl=50 time=76.8 ms
64 bytes from 96.7.128.175: icmp_seq=2 ttl=50 time=75.7 ms
64 bytes from 96.7.128.175: icmp_seq=3 ttl=50 time=80.9 ms
64 bytes from 96.7.128.175: icmp_seq=4 ttl=50 time=74.7 ms
64 bytes from 96.7.128.175: icmp_seq=5 ttl=50 time=92.7 ms
--- 96.7.128.175 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 74.712/80.156/92.723/6.626 ms
# Test DNS
bryan@myPi:~ $ ping example.com
PING example.com (96.7.128.175) 56(84) bytes of data.
64 bytes from a96-7-128-175.deploy.static.akamaitechnologies.com (96.7.128.175): icmp_seq=1 ttl=50 time=77.7 ms
64 bytes from a96-7-128-175.deploy.static.akamaitechnologies.com (96.7.128.175): icmp_seq=2 ttl=50 time=81.2 ms
64 bytes from a96-7-128-175.deploy.static.akamaitechnologies.com (96.7.128.175): icmp_seq=3 ttl=50 time=75.6 ms
64 bytes from a96-7-128-175.deploy.static.akamaitechnologies.com (96.7.128.175): icmp_seq=4 ttl=50 time=79.1 ms
64 bytes from a96-7-128-175.deploy.static.akamaitechnologies.com (96.7.128.175): icmp_seq=5 ttl=50 time=83.3 ms
64 bytes from a96-7-128-175.deploy.static.akamaitechnologies.com (96.7.128.175): icmp_seq=6 ttl=50 time=94.4 ms
^C
--- example.com ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5006ms
rtt min/avg/max/mdev = 75.593/81.884/94.425/6.114 ms
bryan@myPi:~ $ sudo systemctl status NetworkManager
* NetworkManager.service - Network Manager
Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; preset: enabled)
Active: active (running) since Fri 2025-03-28 18:04:20 EDT; 23h ago
Docs: man:NetworkManager(8)
Main PID: 701 (NetworkManager)
Tasks: 3 (limit: 9579)
CPU: 6.238s
CGroup: /system.slice/NetworkManager.service
`-701 /usr/sbin/NetworkManager --no-daemon
Mar 28 18:04:32 myPi NetworkManager[701]: <info> [1743199472.2392] dhcp4 (wlan0): state changed new lease, address=172.16.12.100
Mar 28 18:04:32 myPi NetworkManager[701]: <info> [1743199472.2396] policy: set 'preconfigured' (wlan0) as default for IPv4 routing and DNS
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.8970] device (wlan0): state change: ip-config -> ip-check (reason 'none', sys-i>
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.9288] device (wlan0): state change: ip-check -> secondaries (reason 'none', sys>
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.9289] device (wlan0): state change: secondaries -> activated (reason 'none', sy>
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.9292] manager: NetworkManager state is now CONNECTED_SITE
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.9308] device (wlan0): Activation: successful, device activated.
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.9312] manager: NetworkManager state is now CONNECTED_GLOBAL
Mar 28 18:04:33 myPi NetworkManager[701]: <info> [1743199473.9316] manager: startup complete
Mar 29 09:43:20 myPi NetworkManager[701]: <info> [1743255800.7989] dhcp4 (wlan0): state changed new lease, address=172.16.12.100
# To restart the NetworkManager
$ sudo systemctl restart NetworkManager
5. "Segmentation fault"
Cause: Program accessed memory incorrectly—likely a bug.
✅ Fix:
# Try updating or reinstalling:
sudo apt update -y && sudo apt upgrade -y && sudo apt clean
sudo apt install --reinstall <package>
Advanced: Debug with gdb (GNU Debugger) or check logs
6. "Package has unmet dependencies"
Cause: Conflicting or broken package installation.
✅ Fix:
sudo apt --fix-broken install
Fix broken package dependencies on Debian-based systems
sudo dpkg --configure -a
A critical recovery command for fixing broken or incomplete package installations in Debian-based systems
sudo apt clean && sudo apt update
Deletes the local package cache and refreshes your system’s list of available packages from all configured repositories
7. "Cannot open display"
Cause: Trying to launch a GUI app without X11 display access.
When a GUI app starts, it needs to connect to the X server to draw its interface (windows, dialogs, menus).
If one of the following is true:
- There’s no
$DISPLAY
environment variable set - You're connected over SSH without X11 forwarding
- You're on a headless system (no graphical environment)
- You're using
sudo
and the root user doesn't inherit your display
…the GUI app fails with:Cannot open display
✅ Fix:
export DISPLAY=:0 # Local GUI
Sets the environment variable DISPLAY
so that apps know which X server to connect to.
and/or
ssh -X user@host # or use -Y for trusted forwarding
Ensure:
- The remote system has X11 installed
- The remote SSH server has
X11Forwarding yes
in/etc/ssh/sshd_config
- Your local system is running an X server (Linux, XQuartz for macOS, VcXsrv for Windows)
sudo env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY your_gui_app
# OR
sudo -E your_gui_app
Running as root (via sudo)
On a headless system? Use a virtual X server:
sudo apt install xvfb
xvfb-run your_gui_app
8. "Read-only file system"
Cause: This is almost always a safety mechanism triggered by the kernel due to I/O errors.
🧪Diagnose:
mount | grep 'ro,'
Check the mounted filesystems. Should see something like (ro,relatime,errors=remount-ro)
dmesg | grep -i "error"
Check system logs
You’ll often see I/O errors, kernel complaints, or journal failures.
✅ Fix:
First — Reboot: sudo reboot
If it still comes back read-only...
🔧 Run Filesystem Check (fsck):
bryan@myPi:~ $ sudo fsck -y /dev/mmcblk0p2
fsck from util-linux 2.38.1
e2fsck 1.47.0 (5-Feb-2023)
/dev/mmcblk0p2 is mounted.
e2fsck: Cannot continue, aborting.
⚠️ This must be done with the filesystem unmounted. Boot from a live CD (or secondary OS)
Once unmounted:
bryan@myPi:~ $ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
mmcblk0 179:0 0 58.2G 0 disk
|-mmcblk0p1 179:1 0 512M 0 part /boot/firmware
`-mmcblk0p2 179:2 0 57.7G 0 part /
Identify the partition (e.g., /dev/sda1
, /dev/mmcblk0p2
)
$ sudo fsck -y /dev/mmcblk0p2
This will scan and fix errors.
🧱 If you're on a Raspberry Pi:
sudo touch /forcefsck
sudo reboot
That will force a fsck
check on the next boot.
💡 Pro Tip:
If it keeps happening, your SD card, SSD, or HDD is likely failing. Don’t ignore the warning — back up your data immediately.
🧯 Temporary remount fix (if disk is still healthy):
If you're sure the issue isn’t hardware-related:
sudo mount -o remount,rw /
This is a temporary fix. If the root cause isn’t fixed, it’ll revert or crash again.
10. "Connection refused"
Cause: …it means your machine reached the target, but the port is closed, and no service is listening on that port.
Translation: “The door exists, but nobody’s answering.”
✅ 1. Is the service running?
sudo systemctl status <your_service>
and/or list all active ports:
bryan@myPi:~ $ sudo netstat -tulnp | grep LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 806/sshd: /usr/sbin
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 4338/cupsd
tcp6 0 0 :::5900 :::* LISTEN 756/wayvnc
tcp6 0 0 :::22 :::* LISTEN 806/sshd: /usr/sbin
tcp6 0 0 ::1:631 :::* LISTEN 4338/cupsd
Is your service on the correct IP/port?
Or
bryan@myPi:~ $ sudo ss -tulnp | grep LISTEN
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=806,fd=3))
tcp LISTEN 0 128 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=4338,fd=7))
tcp LISTEN 0 16 *:5900 *:* users:(("wayvnc",pid=756,fd=8))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=806,fd=4))
tcp LISTEN 0 128 [::1]:631 [::]:* users:(("cupsd",pid=4338,fd=6))
✅ 2. Is the correct port open?
Make sure the expected port is active.
Example (for port 80):
$ telnet localhost 80
#OR
$ nc -zv localhost 80
If you get "Connection refused", the service isn’t listening.
✅ 3. Firewall blocking it?
Use ufw
or iptables
to check:
sudo ufw status verbose
sudo iptables -L -n
If your service listens on port 8080, but firewall blocks it:
sudo ufw allow 8080
✅ 4. Binding to the wrong interface?
bryan@myPi:~ $ ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:631 0.0.0.0:*
LISTEN 0 16 *:5900 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:631 [::]:*
If it shows LISTEN 127.0.0.1:8080
...you can’t connect remotely — only from localhost.
Fix your service config to bind to: 0.0.0.0:8080
Or specifically: your.lan.ip:8080
✅ 5. SELinux or AppArmor interference
If you're running RHEL/CentOS or using SELinux AppArmor could be interfering:
$ getenforce
# If it's "Enforcing", try temporarily setting to:
$ sudo setenforce 0
For AppArmor (Ubuntu/Debian), check if it's limiting the service:
bryan@myPi:~ $ sudo apparmor_status
apparmor module is loaded.
apparmor filesystem is not mounted.
to see if AppArmor is running and if any profiles are in "enforce" mode
Or
bryan@myPi:~ $ sudo systemctl status apparmor
* apparmor.service - Load AppArmor profiles
Loaded: loaded (/lib/systemd/system/apparmor.service; enabled; preset: enabled)
Active: inactive (dead)
Condition: start condition failed at Fri 2025-03-28 17:17:04 EDT; 1 day 2h ago
Docs: man:apparmor(7)
https://gitlab.com/apparmor/apparmor/wikis/home/
Mar 28 17:17:04 myPi systemd[1]: apparmor.service - Load AppArmor profiles was skipped because of an unmet condition check (ConditionSecurity=apparmor).
Mar 28 17:17:04 myPi systemd[1]: apparmor.service - Load AppArmor profiles was skipped because of an unmet condition check (ConditionSecurity=apparmor).
to check the status of the AppArmor service.
✅ 6. Wrong address or port?
Triple-check:
- Hostname or IP address
- Port number
- Protocol (TCP/UDP)
🧠 Wrapping It Up
Linux errors aren’t just frustrating—they’re opportunities to level up your problem-solving skills. Whether it's a misbehaving service or a missing package, knowing how to cut through the noise is what separates casual users from confident operators.
Got an error that’s not on this list? Or a gnarly bug that had you pulling your hair out for hours? Drop it in the comments or shoot it my way—I’m always collecting new war stories for future posts.
Until next time: stay sharp, stay curious, and keep those terminals clean. ✌️
– Bryan Steele