Error Message Decoder

What 121 common Linux, Windows, Docker and SSL errors mean, and how to fix them
Paste an error message, or a few lines of a log, and get what it means, why it usually happens and how to fix it. It covers 121 of the errors sysadmins search for most, across Linux, Windows, Docker, Kubernetes, SSL and web servers.
RUNS ENTIRELY IN YOUR BROWSER · WHAT YOU PASTE NEVER LEAVES IT

Examples:

Matching happens as you type. Paths, hostnames and numbers don't need to match.

🔑 SSH (12) · For a whole ssh -v log, use SSH Doctor

SSH private key permissions are too open

🔑 SSH
WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for '/home/user/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others. This private key will be ignored.

What it means: OpenSSH refuses to use a private key that other users can read, so it skips the key and falls back to other methods (usually ending in a password prompt or Permission denied (publickey)).

Common causes

  • The key was copied from another machine, a USB stick or a zip file and kept loose permissions.
  • On Windows, the key file inherits access for other users or groups.
  • Someone ran chmod -R 755 ~/.ssh or similar.

How to fix it

  1. Make the key readable by you only, and the folder private:

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/id_rsa
  2. Public keys (.pub), known_hosts and config can be 644, but config must not be writable by others:

    chmod 644 ~/.ssh/id_rsa.pub ~/.ssh/known_hosts
    chmod 600 ~/.ssh/config
  3. On Windows (PowerShell), remove inherited access and give only your user read access:

    icacls $env:USERPROFILE\.ssh\id_rsa /inheritance:r
    icacls $env:USERPROFILE\.ssh\id_rsa /grant:r "$($env:USERNAME):(R)"

Careful: Don't chmod the key 777 or 755 to make the error go away. The check exists to protect the key.

Permission denied (publickey)

🔑 SSH
Permission denied (publickey).
user@host: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
git@github.com: Permission denied (publickey).

What it means: The server only accepts key logins, and none of the keys your client offered is in that user's authorized_keys.

Common causes

  • Your public key isn't in ~/.ssh/authorized_keys on the server, or it's in the wrong user's account.
  • The client is offering a different key than the one you installed (check which with ssh -v).
  • Wrong username, for example ssh host when the account is ubuntu, ec2-user or admin.
  • On the server, ~ or ~/.ssh is writable by others, so sshd ignores authorized_keys (StrictModes).

How to fix it

  1. See which keys are offered and why each is rejected:

    ssh -v user@host
  2. Use a specific key and username:

    ssh -i ~/.ssh/id_ed25519 user@host
  3. Install your public key on the server (needs another way in, such as a password or console):

    ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
  4. On the server, fix ownership and permissions of the user's SSH folder:

    chown -R user:user ~user/.ssh
    chmod 700 ~user/.ssh
    chmod 600 ~user/.ssh/authorized_keys
  5. Check the server log for the real reason:

    sudo journalctl -u ssh -u sshd --since '10 min ago'
  6. For GitHub or GitLab, add the public key to your account settings, then test:

    ssh -T git@github.com

Remote host identification has changed

🔑 SSH
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Host key verification failed.

What it means: The server's host key doesn't match the one saved in your known_hosts. SSH stops because this is exactly what a man-in-the-middle attack looks like.

Common causes

  • The server was rebuilt or reinstalled, so it generated new host keys.
  • The IP address or hostname now points to a different machine (new VM, DHCP, load balancer).
  • Rarely, a real interception attempt.

How to fix it

  1. Confirm the new fingerprint with whoever runs the server (or from its console):

    ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
  2. Then remove only the old entry for that host and connect again:

    ssh-keygen -R hostname
    ssh-keygen -R 192.0.2.10
  3. The warning names the line number too (Offending ECDSA key in ~/.ssh/known_hosts:12), if you prefer to delete that line by hand.

Careful: Don't turn off StrictHostKeyChecking to get past this. Verify the new key first.

Host key verification failed

🔑 SSH
Host key verification failed.
fatal: Could not read from remote repository.

What it means: SSH couldn't confirm the server's identity, so it closed the connection before logging in.

Common causes

  • The host isn't in known_hosts yet and SSH can't ask you (a script, cron job, CI runner or git without a terminal).
  • The saved host key no longer matches (see Remote host identification has changed).
  • Running as a different user (for example under sudo or a service account) with its own empty known_hosts.

How to fix it

  1. Connect once by hand as the same user that runs the job, check the fingerprint and accept it:

    ssh user@host
  2. Or add the host key ahead of time (check it against a trusted source):

    ssh-keyscan -H host >> ~/.ssh/known_hosts
  3. For GitHub, compare with the fingerprints GitHub publishes, then add:

    ssh-keyscan github.com >> ~/.ssh/known_hosts

Careful: Avoid -o StrictHostKeyChecking=no in scripts; it accepts any server, including an attacker's.

No matching host key type found

🔑 SSH
Unable to negotiate with 192.0.2.10 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
no matching cipher found. Their offer: aes128-cbc,3des-cbc

What it means: Your SSH client and an old server have no algorithm in common. Newer OpenSSH (8.8+) disables ssh-rsa (SHA-1) and other weak algorithms by default.

Common causes

  • The server is old: network gear, a NAS, a legacy appliance or an unpatched Linux box.
  • Your client was upgraded and dropped the old algorithms.

How to fix it

  1. Best fix: update the server or its firmware so it offers modern algorithms (ed25519, rsa-sha2-256/512, curve25519).

  2. As a temporary workaround for that one host only, re-enable the algorithm it offers:

    ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa user@host
  3. For an old key exchange or cipher, the same pattern works:

    ssh -o KexAlgorithms=+diffie-hellman-group14-sha1 user@host
    ssh -c aes128-cbc user@host
  4. To make it permanent for that host only, put the options under a Host block in ~/.ssh/config.

Careful: Don't add weak algorithms globally (under Host *). Limit them to the device that needs them.

Could not open a connection to your authentication agent

🔑 SSH
Could not open a connection to your authentication agent.
Error connecting to agent: No such file or directory

What it means: ssh-add can't find a running ssh-agent, because the SSH_AUTH_SOCK variable isn't set in this shell.

Common causes

  • The agent was never started in this session (common in plain terminals, tmux and over SSH).
  • The agent runs, but this shell didn't load its environment variables.
  • On Windows, the OpenSSH Authentication Agent service is stopped or disabled.

How to fix it

  1. Start an agent in the current shell and add your key:

    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_ed25519
  2. On Windows (PowerShell as administrator), enable and start the agent service:

    Get-Service ssh-agent | Set-Service -StartupType Automatic
    Start-Service ssh-agent
    ssh-add $env:USERPROFILE\.ssh\id_ed25519

ssh: connect to host … port 22: Connection refused

🔑 SSH
ssh: connect to host 192.0.2.10 port 22: Connection refused

What it means: Your packet reached the machine, but nothing is listening on that port, so the server actively rejected it.

Common causes

  • The SSH server (sshd) isn't installed or isn't running.
  • SSH listens on a different port (check Port in /etc/ssh/sshd_config).
  • A firewall on the host sends a reject instead of dropping the packet.

How to fix it

  1. On the server (console), check that sshd is running and which port it uses:

    sudo systemctl status ssh sshd
    sudo ss -tlnp | grep ssh
  2. Install and start it if missing (Debian/Ubuntu shown):

    sudo apt install openssh-server
    sudo systemctl enable --now ssh
  3. If it uses another port, connect to that port:

    ssh -p 2222 user@host

ssh: connect to host … Connection timed out

🔑 SSH
ssh: connect to host example.com port 22: Connection timed out
ssh: connect to host 192.0.2.10 port 22: Operation timed out

What it means: No reply came back at all. The packets are being dropped somewhere, or the address is wrong.

Common causes

  • A firewall or cloud security group drops port 22 (AWS security group, Azure NSG, ufw, firewalld).
  • Wrong IP address, or the machine is off or unreachable.
  • Your own network blocks outbound SSH (some office and public Wi-Fi networks).

How to fix it

  1. Check that the host answers at all and where the path stops:

    ping -c 3 host
    traceroute host
  2. Test the port directly:

    nc -vz host 22
  3. Open port 22 for your IP in the cloud security group, and in the host firewall:

    sudo ufw allow 22/tcp
    sudo firewall-cmd --add-service=ssh --permanent && sudo firewall-cmd --reload

Too many authentication failures

🔑 SSH
Received disconnect from 192.0.2.10 port 22:2: Too many authentication failures

What it means: Your SSH agent offered so many keys that the server hit its MaxAuthTries limit (default 6) before trying the right one.

Common causes

  • Many keys loaded in ssh-agent, and the right one is far down the list.

How to fix it

  1. Tell SSH to use only the key you name:

    ssh -o IdentitiesOnly=yes -i ~/.ssh/server_key user@host
  2. Make it permanent in ~/.ssh/config:

    Host myserver
        HostName 192.0.2.10
        User admin
        IdentityFile ~/.ssh/server_key
        IdentitiesOnly yes

kex_exchange_identification: Connection closed by remote host

🔑 SSH
kex_exchange_identification: Connection closed by remote host
kex_exchange_identification: read: Connection reset by peer
ssh_exchange_identification: Connection closed by remote host

What it means: The TCP connection opened, but the server closed it before SSH could even start. Something in front of sshd, or sshd itself, is turning you away.

Common causes

  • fail2ban, DenyHosts or a firewall rule has banned your IP after failed logins.
  • sshd hit MaxStartups (too many unauthenticated connections at once, often from scanners).
  • /etc/hosts.deny or a proxy/jump host is blocking you, or sshd is broken (bad host key permissions).

How to fix it

  1. On the server, read the sshd log at the time you connected:

    sudo journalctl -u ssh -u sshd -n 50
  2. Check whether fail2ban banned you, and unban:

    sudo fail2ban-client status sshd
    sudo fail2ban-client set sshd unbanip 203.0.113.5
  3. Check that the sshd configuration is valid:

    sudo sshd -t

Bad owner or permissions on ~/.ssh/config

🔑 SSH
Bad owner or permissions on /home/user/.ssh/config

What it means: SSH refuses to read a config file that someone else owns or could edit, because it can change which keys and hosts you trust.

Common causes

  • The file is group- or world-writable, or owned by root after editing it with sudo.

How to fix it

  1. Give it back to your user and make it private:

    chown $USER:$USER ~/.ssh/config
    chmod 600 ~/.ssh/config

Load key: invalid format

🔑 SSH
Load key "/home/user/.ssh/id_rsa": invalid format
Load key "id_rsa": error in libcrypto

What it means: SSH can't parse the private key file.

Common causes

  • The key is in PuTTY .ppk format, not OpenSSH format.
  • The file was damaged when copied: Windows line endings, a missing final newline, or extra spaces from pasting.
  • You pointed SSH at the public key (.pub) instead of the private key.

How to fix it

  1. Convert a PuTTY key with puttygen (or use PuTTYgen on Windows: Conversions → Export OpenSSH key):

    puttygen key.ppk -O private-openssh -o ~/.ssh/id_rsa
  2. Fix Windows line endings and make sure the file ends with a newline:

    sed -i 's/\r$//' ~/.ssh/id_rsa
    echo >> ~/.ssh/id_rsa
  3. Check that the key is readable (prints its public half):

    ssh-keygen -y -f ~/.ssh/id_rsa

📦 Packages (15) · The same commands on other distributions: Package Manager Translator

Could not get lock /var/lib/dpkg/lock-frontend

📦 Packages
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (apt)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

What it means: Another program is installing or updating packages right now, and only one can use dpkg at a time.

Common causes

  • Automatic updates (unattended-upgrades) are running, very often right after boot.
  • Another terminal, Software Center or a script is running apt.
  • A previous apt run crashed and left a process behind.

How to fix it

  1. See what holds the lock, then wait for it to finish (usually a few minutes):

    ps aux | grep -E 'apt|dpkg' | grep -v grep
  2. If an apt process is stuck, stop that process (use its PID), then finish any half-done install:

    sudo kill 1234
    sudo dpkg --configure -a

Careful: Don't delete the lock files while apt or dpkg is still running. That can corrupt the package database.

E: Unable to locate package

📦 Packages
E: Unable to locate package nginx
E: Package 'foo' has no installation candidate

What it means: apt can't find a package with that name in any repository it knows about.

Common causes

  • The package lists are out of date or empty (common on fresh servers and Docker images): run apt update first.
  • A typo, or the package has a different name on this distro or release.
  • The package lives in a repository that isn't enabled (for example Ubuntu's universe).

How to fix it

  1. Refresh the package lists, then try again:

    sudo apt update
    sudo apt install nginx
  2. Search for the right name:

    apt search nginx
    apt-cache policy nginx
  3. On Ubuntu, enable the universe repository if the package lives there:

    sudo add-apt-repository universe
    sudo apt update

You have held broken packages

📦 Packages
E: Unable to correct problems, you have held broken packages.
The following packages have unmet dependencies:

What it means: apt can't find a set of package versions that satisfies every dependency, so it refuses to install.

Common causes

  • Packages from a PPA or third-party repo conflict with the official versions.
  • Mixed releases in your sources (for example a newer Debian repo added to an older system).
  • A package is on hold at an old version (apt-mark hold).

How to fix it

  1. See the full chain of what conflicts:

    sudo apt install -f
    sudo apt install <package> --dry-run
  2. List held packages and release any you didn't mean to hold:

    apt-mark showhold
    sudo apt-mark unhold <package>
  3. Check which repository each version comes from:

    apt-cache policy <package>

Careful: Avoid forcing with dpkg --force-depends; it leaves the system in a broken state that later updates trip over.

dpkg was interrupted, you must manually run 'dpkg --configure -a'

📦 Packages
E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.

What it means: A previous install or upgrade stopped halfway (closed terminal, lost SSH session, reboot), so some packages are unpacked but not configured.

Common causes

  • The session running apt was disconnected.
  • The machine rebooted or ran out of disk space during an upgrade.

How to fix it

  1. Finish configuring the half-installed packages, then repair anything still broken:

    sudo dpkg --configure -a
    sudo apt install -f
  2. Run long upgrades inside tmux or screen so a dropped SSH session can't interrupt them.

NO_PUBKEY: the public key is not available

📦 Packages
W: GPG error: https://example.com stable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 1234ABCD5678EF90
E: The repository 'https://example.com stable InRelease' is not signed.

What it means: apt downloaded a repository's index but doesn't have the key that signed it, so it won't trust that repository.

Common causes

  • You added a third-party repository without its signing key.
  • The vendor rotated to a new key.

How to fix it

  1. Download the vendor's key into its own keyring file (use the URL from the vendor's install docs):

    curl -fsSL https://example.com/key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg
  2. Point the repository at that key with signed-by, then update:

    echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/apt stable main" | sudo tee /etc/apt/sources.list.d/example.list
    sudo apt update

Careful: Don't use apt-key add; it's deprecated and trusts the key for every repository. And don't add [trusted=yes] to skip the check.

Release file is not valid yet

📦 Packages
E: Release file for http://archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease is not valid yet (invalid for another 5h 3min 12s). Updates for this repository will not be applied.

What it means: Your system clock is behind, so apt thinks the repository's signed index comes from the future.

Common causes

  • Wrong date or time, often on VMs restored from a snapshot, Raspberry Pis without a clock battery, or WSL after sleep.

How to fix it

  1. Check the clock and turn on time sync:

    timedatectl
    sudo timedatectl set-ntp true
  2. On WSL, restart WSL from Windows to resync the clock:

    wsl --shutdown

The repository does not have a Release file

📦 Packages
E: The repository 'http://archive.ubuntu.com/ubuntu impish Release' does not have a Release file.
E: The repository 'http://ppa.launchpad.net/foo/ubuntu noble Release' no longer has a Release file.

What it means: That repository doesn't publish packages for your release (any more).

Common causes

  • Your Ubuntu or Debian release reached end of life and moved to the old-releases archive.
  • A PPA or vendor repo has no build for your release yet, or was removed.

How to fix it

  1. Find the file that adds the repository:

    grep -r 'ppa.launchpad.net/foo' /etc/apt/sources.list /etc/apt/sources.list.d/
  2. Remove or comment out that repository, then update:

    sudo add-apt-repository --remove ppa:foo/bar
    sudo apt update
  3. For an end-of-life release, upgrade to a supported release (or point the sources at old-releases.ubuntu.com only as a stopgap).

Hash Sum mismatch

📦 Packages
E: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy/main/binary-amd64/Packages.xz  Hash Sum mismatch

What it means: A downloaded index file didn't match its expected checksum, so apt discarded it.

Common causes

  • A mirror was syncing when you downloaded.
  • A caching proxy or captive portal served a stale or altered file.

How to fix it

  1. Clear the cached lists and try again:

    sudo rm -rf /var/lib/apt/lists/*
    sudo apt clean
    sudo apt update
  2. If it persists, switch to a different mirror in your sources, or bypass the proxy.

Sub-process /usr/bin/dpkg returned an error code (1)

📦 Packages
E: Sub-process /usr/bin/dpkg returned an error code (1)
dpkg: error processing package foo (--configure):

What it means: This line is a summary. dpkg failed on one package, and the real reason is printed a few lines above it.

Common causes

  • A package's install script failed (a service that won't start, a config file error).
  • Disk full, or a file conflict with another package.

How to fix it

  1. Scroll up for the first dpkg: error processing package line and the error under it. Then retry configuring:

    sudo dpkg --configure -a
    sudo apt install -f
  2. If one package keeps failing, reinstall it to see its own error:

    sudo apt install --reinstall <package>
  3. Check free space:

    df -h /var /

Error: Unable to find a match

📦 Packages
Error: Unable to find a match: htop
No match for argument: htop
No package htop available.

What it means: dnf or yum can't find that package in any enabled repository.

Common causes

  • The package is in EPEL, which isn't enabled (common on RHEL, Rocky and AlmaLinux).
  • A different package name on this distro, or a typo.
  • The repository metadata is stale.

How to fix it

  1. Search, and find which package provides a command:

    dnf search htop
    dnf provides '*/bin/htop'
  2. Enable EPEL on RHEL-compatible systems:

    sudo dnf install epel-release
  3. Refresh metadata:

    sudo dnf clean all
    sudo dnf makecache

GPG check FAILED / Public key is not installed

📦 Packages
The GPG keys listed for the "Example" repository are already installed but they are not correct for this package.
Public key for foo-1.2.rpm is not installed
Error: GPG check FAILED

What it means: The package's signature can't be checked against a key you trust, so dnf refuses to install it.

Common causes

  • The repository's signing key was never imported, or the vendor rotated keys.

How to fix it

  1. Import the vendor's key from the URL in their docs, then retry:

    sudo rpm --import https://example.com/RPM-GPG-KEY-example
  2. Check that the gpgkey= line in /etc/yum.repos.d/<repo>.repo points to the current key.

Careful: Don't use --nogpgcheck or gpgcheck=0 to get past this, except for packages you built yourself.

Cannot find a valid baseurl / Failed to download metadata

📦 Packages
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
Cannot find a valid baseurl for repo: base/7/x86_64

What it means: dnf or yum couldn't reach any mirror for a repository.

Common causes

  • The release is end of life and its mirrors were retired (CentOS 7 since June 2024, CentOS 8 since 2022).
  • No DNS or internet access, or a proxy isn't configured.

How to fix it

  1. Test name resolution and access first:

    getent hosts mirrorlist.centos.org
    curl -I https://dl.fedoraproject.org
  2. For an end-of-life CentOS, move to a supported distro (Rocky, AlmaLinux, RHEL); pointing repos at vault.centos.org only buys time.

  3. Disable a broken third-party repo for one run:

    sudo dnf --disablerepo=<repo-id> upgrade

Waiting for process with pid … to finish (dnf/yum lock)

📦 Packages
Waiting for process with pid 1234 to finish.
Another app is currently holding the yum lock; waiting for it to exit...

What it means: Another dnf or yum run, often the automatic update service, is using the package database.

Common causes

  • dnf-automatic, PackageKit or GNOME Software is updating in the background.

How to fix it

  1. See what it is and let it finish:

    ps -fp 1234
  2. If it's hung, stop it, then check the database:

    sudo kill 1234
    sudo rpm --rebuilddb

error: externally-managed-environment

📦 Packages
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install python3-xyz

What it means: Your distro's Python is managed by the system package manager (PEP 668), so pip won't install into it.

Common causes

  • Debian 12+, Ubuntu 23.04+, Fedora and others mark the system Python as externally managed.

How to fix it

  1. Use a virtual environment for your project:

    python3 -m venv .venv
    . .venv/bin/activate
    pip install requests
  2. For command-line tools, use pipx:

    sudo apt install pipx
    pipx install httpie
  3. Or install the distro's packaged version:

    sudo apt install python3-requests

Careful: Avoid --break-system-packages on servers; it can break tools the OS itself depends on.

WARNING: apt does not have a stable CLI interface

📦 Packages
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

What it means: Only a warning: you used apt in a script or pipe. Its output format may change between versions.

Common causes

  • apt is meant for people at a terminal.

How to fix it

  1. In scripts, use the stable tools instead:

    apt-get install -y nginx
    apt-cache policy nginx
    dpkg-query -W nginx

🐳 Docker (10)

Cannot connect to the Docker daemon

🐳 Docker
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

What it means: The docker command can't reach the Docker engine.

Common causes

  • The Docker service isn't running (or Docker Desktop isn't started).
  • DOCKER_HOST or the docker context points somewhere else.
  • Inside WSL or a container, where systemd or the socket isn't available.

How to fix it

  1. Start Docker and make it start at boot:

    sudo systemctl enable --now docker
    sudo systemctl status docker
  2. If it won't start, read why:

    sudo journalctl -u docker -n 50
  3. Check where the CLI is pointing:

    docker context ls
    echo $DOCKER_HOST

Permission denied while trying to connect to the Docker daemon socket

🐳 Docker
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: dial unix /var/run/docker.sock: connect: permission denied

What it means: Docker is running, but your user isn't allowed to use its socket.

Common causes

  • Your user isn't in the docker group, or you were added but haven't logged in again.

How to fix it

  1. Add yourself to the docker group, then start a new login session:

    sudo usermod -aG docker $USER
    newgrp docker
  2. Check:

    id -nG
    docker ps

Careful: Membership of the docker group is effectively root access. Only add trusted users, and don't chmod 666 the socket.

Bind for 0.0.0.0:80 failed: port is already allocated

🐳 Docker
Error response from daemon: driver failed programming external connectivity on endpoint web: Bind for 0.0.0.0:80 failed: port is already allocated
Error starting userland proxy: listen tcp4 0.0.0.0:8080: bind: address already in use

What it means: The host port you're publishing with -p is already taken, by another container or a program on the host.

Common causes

  • Another container already publishes that port (often an old copy of the same one).
  • A host service such as nginx or Apache is listening on it.

How to fix it

  1. Find what uses the port:

    docker ps --filter publish=80
    sudo ss -tlnp | grep ':80 '
  2. Stop the old container, or publish on a different host port:

    docker stop <container>
    docker run -p 8081:80 nginx

no space left on device (Docker)

🐳 Docker
failed to register layer: write /usr/lib/x: no space left on device
Error response from daemon: mkdir /var/lib/docker/overlay2/...: no space left on device

What it means: The disk holding Docker's data (/var/lib/docker) is full.

Common causes

  • Old images, stopped containers, build cache and unused volumes pile up over time.
  • Container logs growing without limits.

How to fix it

  1. See what Docker is using:

    docker system df
    df -h /var/lib/docker
  2. Remove unused data (asks first; add --volumes only if you're sure the volumes are unused):

    docker system prune
    docker builder prune
  3. Limit log size for all containers in /etc/docker/daemon.json, then restart Docker:

    { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }

Careful: docker system prune -a --volumes deletes all unused images and volumes, including data you may want. Read what it lists before saying yes.

exec format error

🐳 Docker
exec /usr/local/bin/docker-entrypoint.sh: exec format error
standard_init_linux.go:228: exec user process caused: exec format error
WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64)

What it means: The container's program was built for a different CPU architecture, or the script has no valid interpreter line.

Common causes

  • An arm64 image (built on an Apple Silicon Mac) running on an x86-64 server, or the reverse.
  • An entrypoint script without a #!/bin/sh first line, or saved with Windows line endings.

How to fix it

  1. Check the image's architecture against the host:

    docker image inspect <image> --format '{{.Os}}/{{.Architecture}}'
    uname -m
  2. Build for the target platform (or both):

    docker buildx build --platform linux/amd64,linux/arm64 -t myimage --push .
  3. For scripts, add a shebang and convert line endings:

    sed -i 's/\r$//' docker-entrypoint.sh

pull access denied, repository does not exist

🐳 Docker
Error response from daemon: pull access denied for myapp, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

What it means: The registry wouldn't give you that image: it doesn't exist under that name, or it's private.

Common causes

  • A typo in the image name or tag, or a missing registry/namespace prefix.
  • A private image and you're not logged in to that registry.
  • You meant a locally built image but it was never built (or was built under another name).

How to fix it

  1. Check local images and the exact name:

    docker images | grep myapp
  2. Log in to the right registry, then pull with the full name:

    docker login ghcr.io
    docker pull ghcr.io/owner/myapp:1.2

toomanyrequests: You have reached your pull rate limit

🐳 Docker
Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading

What it means: Docker Hub limits image pulls per address, and you've hit that limit.

Common causes

  • Anonymous pulls from a shared IP (CI runners, NAT, offices).
  • A CI pipeline pulling the same images on every run.

How to fix it

  1. Log in, which raises the limit:

    docker login
  2. Use a pull-through cache or mirror the images you depend on into your own registry.

OCI runtime create failed: executable file not found in $PATH

🐳 Docker
OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "bash": executable file not found in $PATH: unknown

What it means: The command you asked the container to run doesn't exist inside the image.

Common causes

  • Small images (Alpine, distroless, busybox) have no bash.
  • A typo in CMD/ENTRYPOINT, or the program isn't installed in the image.

How to fix it

  1. Use the shell the image has:

    docker exec -it <container> sh
  2. Check the image's configured command:

    docker image inspect <image> --format '{{.Config.Entrypoint}} {{.Config.Cmd}}'

Conflict. The container name is already in use

🐳 Docker
docker: Error response from daemon: Conflict. The container name "/web" is already in use by container "3f2a…". You have to remove (or rename) that container to be able to reuse that name.

What it means: A container with that name already exists, even if it's stopped.

Common causes

  • You ran the same docker run --name twice; the first container is stopped but not removed.

How to fix it

  1. Remove the old one (or start it instead):

    docker rm -f web
    docker start web
  2. Use --rm for throwaway containers so they're removed when they stop.

Container exited with code 137 (OOMKilled)

🐳 Docker
Exited (137)
OOMKilled: true
command terminated with exit code 137

What it means: Code 137 means the process was killed with SIGKILL (128 + 9). Most often the kernel's out-of-memory killer did it.

Common causes

  • The container hit its memory limit (--memory, Compose mem_limit, Kubernetes limits).
  • The host ran out of memory.
  • Something ran docker kill or the stop timeout expired.

How to fix it

  1. Check whether memory was the cause:

    docker inspect <container> --format '{{.State.OOMKilled}}'
    dmesg -T | grep -i 'killed process'
  2. Give it more memory, or find why it uses so much:

    docker stats
    docker run --memory 1g myimage

🔒 SSL / TLS (10) · Need another format? Certificate Converter

unable to get local issuer certificate

🔒 SSL / TLS
curl: (60) SSL certificate problem: unable to get local issuer certificate
verify error:num=20:unable to get local issuer certificate

What it means: The client can't build a chain from the server's certificate up to a root CA it trusts.

Common causes

  • The server sends its certificate without the intermediate certificate(s). Browsers often cope; curl, Python and Java don't.
  • The client's CA bundle is missing or outdated.
  • A corporate proxy re-signs HTTPS traffic with its own CA, which this machine doesn't trust.

How to fix it

  1. See exactly what the server sends (look at the chain and Verify return code):

    openssl s_client -connect example.com:443 -servername example.com </dev/null
  2. If you run the server, serve the full chain: in nginx use the fullchain.pem file, in Apache add the intermediate to SSLCertificateFile.

  3. Update the client's CA certificates:

    sudo apt install --reinstall ca-certificates
    sudo update-ca-certificates
  4. Trust a company or private CA system-wide (Debian/Ubuntu shown; RHEL uses /etc/pki/ca-trust/source/anchors + update-ca-trust):

    sudo cp corp-root.crt /usr/local/share/ca-certificates/
    sudo update-ca-certificates

Careful: Don't fix it with curl -k, verify=False or GIT_SSL_NO_VERIFY. That turns off the protection completely.

[SSL: CERTIFICATE_VERIFY_FAILED] (Python, pip)

🔒 SSL / TLS
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)
pip install fails with "connection error: [SSL: CERTIFICATE_VERIFY_FAILED]"

What it means: Python couldn't verify the server's certificate against the CA certificates it uses.

Common causes

  • On macOS with python.org Python, the bundled certificates were never installed.
  • A corporate proxy or antivirus intercepts HTTPS with its own CA.
  • Python's certifi bundle is out of date, or the server is missing its intermediate certificate.

How to fix it

  1. On macOS (python.org installer), run the certificate installer that ships with Python (use your version number):

    /Applications/Python\ 3.12/Install\ Certificates.command
  2. Update certifi:

    python3 -m pip install --upgrade certifi
  3. Behind a company proxy, point Python and pip at your company's CA bundle:

    export REQUESTS_CA_BUNDLE=/path/to/corp-ca.pem
    pip config set global.cert /path/to/corp-ca.pem

Careful: Avoid --trusted-host and verify=False except for a quick test; they let anyone in the middle feed you packages.

certificate has expired

🔒 SSL / TLS
SSL certificate problem: certificate has expired
NET::ERR_CERT_DATE_INVALID
x509: certificate has expired or is not yet valid

What it means: The certificate's validity dates don't include the current time.

Common causes

  • The certificate really expired (renewal job failed or was never set up).
  • The client's clock is wrong (VM snapshots, dead clock battery, no NTP).
  • An expired intermediate or root is still being served or trusted on an old client.

How to fix it

  1. Check the dates the server sends:

    echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
  2. Check the client's clock:

    date
    timedatectl
  3. For Let's Encrypt, test and fix renewal, then reload the web server:

    sudo certbot renew --dry-run
    sudo systemctl reload nginx

self-signed certificate in certificate chain

🔒 SSL / TLS
SSL certificate problem: self-signed certificate in certificate chain
self signed certificate in certificate chain
x509: certificate signed by unknown authority

What it means: The chain ends in a root CA the client doesn't trust: a self-signed or private CA.

Common causes

  • An internal service uses a self-signed certificate or a company CA.
  • A corporate proxy or antivirus inspects HTTPS traffic.
  • Docker or Go programs use their own CA store, separate from your browser's.

How to fix it

  1. Trust the CA properly on the client (Debian/Ubuntu shown):

    sudo cp my-ca.crt /usr/local/share/ca-certificates/
    sudo update-ca-certificates
  2. For a Docker registry with a private CA, put the CA where Docker looks:

    sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
    sudo cp my-ca.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt
  3. For public sites, get a certificate from a public CA (for example Let's Encrypt) instead of self-signing.

Careful: Don't disable verification in code or with -k. Trust the specific CA instead.

Certificate doesn't match the hostname

🔒 SSL / TLS
curl: (60) SSL: no alternative certificate subject name matches target host name 'example.com'
NET::ERR_CERT_COMMON_NAME_INVALID
x509: certificate is valid for www.example.com, not example.com
Hostname/IP does not match certificate's altnames

What it means: The certificate is valid, but not for the name you connected to.

Common causes

  • The certificate covers www.example.com but not example.com (or the reverse).
  • You connected by IP address, or by an internal name not on the certificate.
  • The server sends the default certificate because SNI didn't match any configured site.

How to fix it

  1. See which names the certificate covers:

    echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -ext subjectAltName
  2. Reissue the certificate with every name you use (Let's Encrypt shown):

    sudo certbot --nginx -d example.com -d www.example.com
  3. Connect using a name that's on the certificate.

PKIX path building failed (Java)

🔒 SSL / TLS
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

What it means: Java couldn't find a trusted path to the server's certificate in its own truststore (cacerts), which is separate from the OS's.

Common causes

  • A private or company CA, or a proxy that inspects HTTPS.
  • The server doesn't send its intermediate certificate.
  • An old JDK with an outdated cacerts.

How to fix it

  1. Import the CA into the JDK's truststore (default password changeit):

    sudo keytool -importcert -alias corp-ca -file corp-ca.crt -cacerts -storepass changeit
  2. Or update the JDK. If you run the server, make it send the full chain.

wrong version number / ssl_error_rx_record_too_long

🔒 SSL / TLS
SSL routines:ssl3_get_record:wrong version number
SSL_ERROR_RX_RECORD_TOO_LONG
ERR_SSL_PROTOCOL_ERROR
curl: (35) error:0A00010B:SSL routines::wrong version number

What it means: The client started a TLS handshake, but the server answered with plain HTTP (or something else that isn't TLS).

Common causes

  • https:// pointed at a port that serves plain HTTP (for example https://host:80 or an app port).
  • The web server listens on 443 without SSL turned on (listen 443; instead of listen 443 ssl;).
  • A proxy setting sends HTTPS traffic to an HTTP-only proxy port.

How to fix it

  1. Test what the port speaks:

    curl -v http://host:443/
    openssl s_client -connect host:443
  2. In nginx, make sure the listener has ssl:

    listen 443 ssl;
    ssl_certificate     /etc/ssl/fullchain.pem;
    ssl_certificate_key /etc/ssl/privkey.pem;
  3. In Apache, enable the SSL module and site:

    sudo a2enmod ssl
    sudo a2ensite default-ssl
    sudo systemctl reload apache2

key values mismatch (certificate and private key do not match)

🔒 SSL / TLS
SSL_CTX_use_PrivateKey("/etc/ssl/private/site.key") failed (SSL: error:05800074:x509 certificate routines::key values mismatch)
AH02565: Certificate and private key urlname:443:0 from /etc/ssl/site.crt and /etc/ssl/site.key do not match

What it means: The private key in your config isn't the one the certificate was issued for.

Common causes

  • A renewed certificate paired with an old key, or files from different orders mixed up.
  • The certificate and intermediate are concatenated in the wrong order (server certificate must come first).

How to fix it

  1. Compare the public key of each; the two hashes must be identical:

    openssl x509 -noout -pubkey -in site.crt | openssl sha256
    openssl pkey -pubout -in site.key | openssl sha256
  2. Find the matching key (or reissue the certificate from your key), and put the server certificate first in a full-chain file.

unable to load certificate / no start line

🔒 SSL / TLS
unable to load certificate
140...:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: TRUSTED CERTIFICATE
Could not read certificate from cert.pem

What it means: OpenSSL expected a PEM file (text starting with -----BEGIN CERTIFICATE-----) but got something else.

Common causes

  • The file is DER (binary), common for .cer and .der files from Windows.
  • It's a PKCS#12/PFX bundle, not a single certificate.
  • Extra text, Windows line endings or a BOM before the BEGIN line, or you passed a key where a certificate was expected.

How to fix it

  1. Look at the start of the file:

    head -c 64 cert.cer | xxd | head -3
  2. Convert DER to PEM:

    openssl x509 -inform der -in cert.cer -out cert.pem
  3. Pull the certificate and key out of a PFX:

    openssl pkcs12 -in bundle.pfx -clcerts -nokeys -out cert.pem
    openssl pkcs12 -in bundle.pfx -nocerts -nodes -out key.pem

Let's Encrypt: Challenge failed for domain

🔒 SSL / TLS
Certbot failed to authenticate some domains (authenticator: nginx).
Challenge failed for domain example.com
Detail: 203.0.113.5: Invalid response from http://example.com/.well-known/acme-challenge/abc123: 404
Timeout during connect (likely firewall problem)

What it means: Let's Encrypt tried to reach your server to prove you control the domain, and the check failed.

Common causes

  • Port 80 is closed in the firewall or cloud security group (the HTTP-01 check always uses port 80).
  • The domain's DNS doesn't point at this server yet (or an AAAA record points somewhere else).
  • A redirect, proxy or CDN in front answers instead of your server.

How to fix it

  1. Check the domain points here (both IPv4 and IPv6):

    dig +short A example.com
    dig +short AAAA example.com
    curl -4 ifconfig.me
  2. Make sure port 80 is open, then try a dry run:

    sudo ufw allow 80/tcp
    sudo certbot renew --dry-run
  3. Behind a CDN or for wildcard certificates, use the DNS-01 challenge with your DNS provider's plugin instead.

🌐 Web servers (12)

Forbidden: You don't have permission to access this resource

🌐 Web servers
Forbidden
You don't have permission to access / on this server.
AH01630: client denied by server configuration
AH00035: access to /index.html denied because search permissions are missing on a component of the path

What it means: Apache refused the request, because of its access rules or because it can't read the files.

Common causes

  • No Require all granted for that directory (Apache 2.4 denies by default outside the DocumentRoot).
  • The Apache user (www-data or apache) can't read the files, or can't enter one of the parent folders.
  • There's no index file and directory listing is off.
  • SELinux blocks access to files outside the usual web folders (RHEL family).

How to fix it

  1. Read the exact reason in the error log:

    sudo tail -n 20 /var/log/apache2/error.log
    sudo tail -n 20 /var/log/httpd/error_log
  2. Allow access to the directory in the site config, then reload:

    <Directory /srv/www/site>
        Require all granted
    </Directory>
  3. Make every folder in the path enterable and files readable:

    namei -l /srv/www/site/index.html
    sudo chmod o+x /srv /srv/www
    sudo chmod -R o+r /srv/www/site
  4. On SELinux systems, label the folder for web content:

    sudo semanage fcontext -a -t httpd_sys_content_t '/srv/www(/.*)?'
    sudo restorecon -Rv /srv/www

Careful: Don't chmod 777 the web root. Readable files and enterable folders are all Apache needs.

Could not reliably determine the server's fully qualified domain name

🌐 Web servers
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message

What it means: Only a warning: Apache doesn't know its own hostname. Apache still starts.

Common causes

  • No global ServerName is set.

How to fix it

  1. Set a global ServerName and reload (Debian/Ubuntu shown):

    echo 'ServerName localhost' | sudo tee /etc/apache2/conf-available/servername.conf
    sudo a2enconf servername
    sudo systemctl reload apache2
  2. If Apache still doesn't start, this warning isn't the cause. Look for the real error:

    sudo apachectl configtest
    sudo journalctl -u apache2 -n 30

Address already in use (nginx or Apache port 80/443)

🌐 Web servers
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
no listening sockets available, shutting down

What it means: Another program is already listening on the port the web server wants.

Common causes

  • nginx and Apache are both installed and both try to use port 80.
  • An old instance is still running, or a container publishes the port.
  • In nginx, two listen lines for the same port with conflicting options.

How to fix it

  1. See who holds the port:

    sudo ss -tlnp | grep -E ':(80|443) '
  2. Stop and disable the one you don't want:

    sudo systemctl disable --now apache2
  3. Validate the config and start again:

    sudo nginx -t
    sudo systemctl restart nginx

502 Bad Gateway (nginx)

🌐 Web servers
502 Bad Gateway
connect() failed (111: Connection refused) while connecting to upstream
connect() to unix:/run/php/php8.2-fpm.sock failed (2: No such file or directory) while connecting to upstream
upstream prematurely closed connection while reading response header from upstream

What it means: nginx is fine, but the backend it forwards to (the upstream) didn't give a valid answer.

Common causes

  • The app server or PHP-FPM is down, crashed, or listens on another port or socket.
  • The proxy_pass or fastcgi_pass address is wrong (for example a different PHP version's socket).
  • SELinux stops nginx from connecting to the backend (RHEL family).

How to fix it

  1. Read the nginx error log; it names the upstream and the reason:

    sudo tail -n 30 /var/log/nginx/error.log
  2. Check the backend is running and listening where nginx expects:

    sudo systemctl status php8.2-fpm
    sudo ss -tlnp | grep 3000
    ls -l /run/php/
  3. Test the backend directly from the server:

    curl -v http://127.0.0.1:3000/
  4. On SELinux systems, allow nginx to make network connections:

    sudo setsebool -P httpd_can_network_connect 1

504 Gateway Time-out (nginx)

🌐 Web servers
504 Gateway Time-out
upstream timed out (110: Connection timed out) while reading response header from upstream

What it means: The backend accepted the request but didn't answer within nginx's timeout (60 seconds by default).

Common causes

  • A slow request: long report, big upload processing, slow database query.
  • The backend is overloaded or stuck.

How to fix it

  1. Find what's slow in the backend logs first; raising timeouts only hides it.

  2. If the request legitimately takes long, raise the timeout for that location:

    location /reports/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_read_timeout 300s;
    }
  3. For PHP-FPM, the matching setting is fastcgi_read_timeout, plus PHP's own max_execution_time.

413 Request Entity Too Large

🌐 Web servers
413 Request Entity Too Large
client intended to send too large body: 5242880 bytes

What it means: The upload is bigger than nginx allows. The default limit is only 1 MB.

Common causes

  • client_max_body_size isn't set (1 MB default).

How to fix it

  1. Raise the limit in the http, server or location block, then reload:

    client_max_body_size 50m;
  2. For PHP apps, raise PHP's limits too (upload_max_filesize and post_max_size in php.ini).

directory index of … is forbidden (nginx 403)

🌐 Web servers
directory index of "/var/www/html/" is forbidden
403 Forbidden

What it means: nginx was asked for a folder, found no index file in it, and directory listing is off.

Common causes

  • No index.html (or index.php) in that folder, or the index directive doesn't list it.
  • For PHP sites, index.php isn't in the index line.
  • nginx can't read the folder (error says 13: Permission denied).

How to fix it

  1. Make sure the index file exists and is listed:

    index index.html index.php;
  2. For permission errors, check every folder on the path:

    namei -l /var/www/html/index.html
  3. Only if you really want a file listing, turn it on for that location: autoindex on;

could not build server_names_hash

🌐 Web servers
nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 64

What it means: A server_name is too long (or there are too many) for nginx's internal table size.

Common causes

  • A long hostname, often a cloud load balancer or container hostname.

How to fix it

  1. Raise the bucket size inside the http block, test and reload:

    http {
        server_names_hash_bucket_size 128;
    }
  2. sudo nginx -t && sudo systemctl reload nginx

upstream sent too big header

🌐 Web servers
upstream sent too big header while reading response header from upstream

What it means: The backend's response headers don't fit in nginx's header buffer. Users usually see a 502.

Common causes

  • Large cookies or many Set-Cookie headers, often from login or session data.

How to fix it

  1. Enlarge the proxy buffers for that site:

    proxy_buffer_size 16k;
    proxy_buffers 8 16k;
    proxy_busy_buffers_size 32k;
  2. For PHP-FPM, use the fastcgi_ versions of the same settings.

nginx: configuration file test failed

🌐 Web servers
nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/sites-enabled/app:12
nginx: configuration file /etc/nginx/nginx.conf test failed
nginx: [emerg] "server" directive is not allowed here

What it means: nginx found a mistake in its configuration and won't load it. The [emerg] line names the file and line number.

Common causes

  • A typo, a missing ; or }, or a directive in the wrong block.
  • A directive from a module that isn't installed.

How to fix it

  1. Test the config and read the first error it reports:

    sudo nginx -t
  2. Show the full merged config to find the line:

    sudo nginx -T | less
  3. Only reload once the test passes:

    sudo nginx -t && sudo systemctl reload nginx

Apache: Syntax error / AH00526

🌐 Web servers
AH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/app.conf:
Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration

What it means: Apache found a mistake in its configuration and won't start or reload.

Common causes

  • A typo, or a directive whose module isn't enabled (for example RewriteEngine needs mod_rewrite).

How to fix it

  1. Test the configuration:

    sudo apachectl configtest
  2. Enable the missing module (Debian/Ubuntu), then reload:

    sudo a2enmod rewrite
    sudo systemctl reload apache2

ERR_TOO_MANY_REDIRECTS

🌐 Web servers
ERR_TOO_MANY_REDIRECTS
This page isn't working. example.com redirected you too many times.
curl: (47) Maximum (50) redirects followed

What it means: The site sends the browser in a circle of redirects.

Common causes

  • A proxy or CDN talks to the server over HTTP, and the server redirects every HTTP request to HTTPS (for example Cloudflare's Flexible SSL mode).
  • The app (WordPress site URL, framework setting) and the web server disagree about http/https or www/non-www.

How to fix it

  1. See the redirect chain:

    curl -sIL http://example.com | grep -iE '^(HTTP|location)'
  2. Behind a proxy, redirect based on the forwarded protocol, or use full (strict) TLS between the CDN and your server.

  3. Make the app's configured URL match the real public address.

📡 Network & DNS (7)

Connection refused

📡 Network & DNS
connect: Connection refused
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Connection refused
ECONNREFUSED 127.0.0.1:5432

What it means: The machine answered, but nothing is listening on that port (or a firewall actively rejected you).

Common causes

  • The service isn't running, or it crashed.
  • It listens on a different port, or only on 127.0.0.1 while you connect from another machine (or the reverse).
  • Inside Docker, localhost means the container itself, not the host.

How to fix it

  1. On the server, check what is listening and on which address:

    sudo ss -tlnp
  2. If it shows 127.0.0.1:8080, change the service to listen on 0.0.0.0 (or the server's IP) to accept outside connections.

  3. From a container, reach a service on the host via host.docker.internal (Docker Desktop) or the host's IP.

No route to host

📡 Network & DNS
connect: No route to host
ssh: connect to host 192.0.2.10 port 22: No route to host

What it means: Your machine couldn't find a path to that address, or a firewall answered with "host unreachable".

Common causes

  • The host is down, or the IP is wrong, or it's on a network you have no route to.
  • firewalld/iptables on the target rejects with icmp-host-prohibited (common on RHEL-family).

How to fix it

  1. Check your routes and whether the host answers:

    ip route get 192.0.2.10
    ping -c 3 192.0.2.10
  2. On a RHEL-family target, open the port in firewalld:

    sudo firewall-cmd --add-port=8080/tcp --permanent
    sudo firewall-cmd --reload

Temporary failure in name resolution

📡 Network & DNS
ping: google.com: Temporary failure in name resolution
Could not resolve host: github.com
getaddrinfo ENOTFOUND example.com
Name or service not known

What it means: The machine couldn't turn a name into an IP address, so DNS isn't working (or the name doesn't exist).

Common causes

  • No DNS server configured, or the configured one is unreachable.
  • /etc/resolv.conf was overwritten or points to a resolver that isn't running (WSL, containers, systemd-resolved).
  • A typo in the name, or a record that doesn't exist.

How to fix it

  1. Tell DNS problems from network problems:

    ping -c 2 1.1.1.1
    getent hosts example.com
  2. Check which DNS servers are in use:

    resolvectl status
    cat /etc/resolv.conf
  3. Query a public resolver directly to see if the name exists:

    dig @1.1.1.1 example.com +short

Network is unreachable

📡 Network & DNS
connect: Network is unreachable
ping: connect: Network is unreachable

What it means: Your machine has no route at all for that destination, often no default gateway.

Common causes

  • No default route (network down, DHCP failed, wrong static config).
  • IPv6 address but no IPv6 connectivity (an app tries IPv6 first).

How to fix it

  1. Check addresses and the default route:

    ip addr
    ip route
  2. Bring the connection up again (NetworkManager shown):

    nmcli connection show
    sudo nmcli connection up <name>

Connection reset by peer

📡 Network & DNS
read: Connection reset by peer
ECONNRESET
recv failure: Connection reset by peer

What it means: The other side, or something in between, abruptly closed the connection.

Common causes

  • The server process crashed or restarted mid-request.
  • A firewall, load balancer or proxy dropped an idle or blocked connection.
  • A TLS or protocol mismatch (speaking HTTP to an HTTPS port, or the reverse).

How to fix it

  1. Check the server's own logs at the same moment, and test the port and protocol:

    curl -v https://host:443/
    openssl s_client -connect host:443

rsync: connection unexpectedly closed (code 12)

📡 Network & DNS
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(228)

What it means: The rsync on the other end died or never started, so the transfer stream broke.

Common causes

  • rsync isn't installed on the remote machine.
  • The remote shell prints text on login (a message in .bashrc), which corrupts the stream.
  • The remote disk is full, or the SSH connection dropped.

How to fix it

  1. Check rsync exists on the remote side:

    ssh user@host 'which rsync'
  2. Make sure a non-interactive SSH session prints nothing:

    ssh user@host true | wc -c
  3. Run with more detail to see where it fails:

    rsync -avv --progress src/ user@host:/dest/

EADDRINUSE: address already in use

📡 Network & DNS
Error: listen EADDRINUSE: address already in use :::3000
OSError: [Errno 98] Address already in use

What it means: The app tried to listen on a port that another process already has.

Common causes

  • An older copy of the same app is still running.
  • Another service uses that port.

How to fix it

  1. Find the process on the port, then stop it:

    sudo ss -tlnp 'sport = :3000'
    sudo lsof -i :3000
  2. Or start the app on another port.

🛡 Permissions & shell (9)

user is not in the sudoers file

🛡 Permissions & shell
user is not in the sudoers file.  This incident will be reported.
user is not in the sudoers file. This incident has been reported to the administrator.

What it means: Your account isn't allowed to use sudo.

Common causes

  • The user isn't in the admin group: sudo on Debian/Ubuntu, wheel on RHEL, Fedora and Arch.

How to fix it

  1. As root (or another admin), add the user to the right group:

    usermod -aG sudo alice
    usermod -aG wheel alice
  2. The user must log out and in again. Check with:

    groups alice
  3. If no admin account works, boot into recovery or single-user mode to add one.

Careful: Edit sudo rules only with visudo; a syntax error in /etc/sudoers can lock everyone out of sudo.

sudo: unable to resolve host

🛡 Permissions & shell
sudo: unable to resolve host myserver: Name or service not known
sudo: unable to resolve host (none)

What it means: The machine's hostname isn't listed in /etc/hosts, so sudo can't look it up. Mostly harmless, but slow.

Common causes

  • The hostname was changed (or set by cloud-init) without updating /etc/hosts.

How to fix it

  1. Check the hostname and add it to /etc/hosts:

    hostnamectl
    echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts

bash: ./script.sh: Permission denied

🛡 Permissions & shell
bash: ./script.sh: Permission denied
-bash: ./deploy.sh: Permission denied

What it means: The shell can't run the file as a program.

Common causes

  • The file has no execute permission.
  • The filesystem is mounted noexec (common for /tmp and some home or USB mounts).

How to fix it

  1. Make it executable, or run it through the interpreter:

    chmod +x script.sh
    ./script.sh
    bash script.sh
  2. Check for noexec on that mount:

    findmnt -no OPTIONS --target ./script.sh

bad interpreter: No such file or directory (^M)

🛡 Permissions & shell
bash: ./script.sh: /bin/bash^M: bad interpreter: No such file or directory
env: 'bash\r': No such file or directory

What it means: The script was saved with Windows line endings (CRLF), so Linux looks for an interpreter called bash\r.

Common causes

  • The file was edited on Windows, or Git converted the line endings on checkout.

How to fix it

  1. Convert the file to Unix line endings:

    sed -i 's/\r$//' script.sh
    # or: dos2unix script.sh
  2. Stop Git converting shell scripts by adding a .gitattributes file to the repo:

    *.sh text eol=lf

command not found

🛡 Permissions & shell
bash: htop: command not found
-bash: kubectl: command not found
zsh: command not found: docker

What it means: The shell couldn't find a program with that name in any folder on your PATH.

Common causes

  • The program isn't installed.
  • It's installed in a folder that isn't on PATH (for example ~/.local/bin, /usr/local/go/bin or /snap/bin).
  • You're in a different shell or user (sudo uses its own PATH via secure_path).

How to fix it

  1. Find which package provides it (apt shown; apt-file needs installing once; see the Package Manager Translator for other systems):

    sudo apt install apt-file && sudo apt-file update
    apt-file search bin/htop
    sudo apt install htop
  2. If it's installed somewhere, add that folder to PATH in ~/.bashrc:

    export PATH="$HOME/.local/bin:$PATH"
  3. Check what the shell sees:

    echo $PATH
    type -a htop

Operation not permitted (even as root)

🛡 Permissions & shell
chattr: Operation not permitted
rm: cannot remove 'file': Operation not permitted
chown: changing ownership of 'file': Operation not permitted

What it means: The action was blocked by something stronger than normal file permissions.

Common causes

  • The file has the immutable (i) or append-only (a) attribute.
  • On an NFS share with root squash, or a filesystem that doesn't support owners (FAT, exFAT, some network shares).
  • SELinux or AppArmor policy, or a container without the needed capability.

How to fix it

  1. Check for special attributes and remove them if they shouldn't be there:

    lsattr file
    sudo chattr -i file
  2. Check what filesystem the file is on:

    findmnt --target file
  3. Look for security-policy denials:

    sudo ausearch -m avc -ts recent
    sudo journalctl -k | grep -i apparmor

sudo: a terminal is required to read the password

🛡 Permissions & shell
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: sorry, you must have a tty to run sudo

What it means: sudo wants a password, but there's no terminal to type it into (a script, cron, CI or Ansible).

Common causes

  • The account needs a password for sudo, and the command runs non-interactively.

How to fix it

  1. Run the automation as a user allowed that one command without a password. Add a rule with visudo:

    sudo visudo -f /etc/sudoers.d/deploy
    # deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp
  2. For Ansible, pass the become password: ansible-playbook site.yml -K

Careful: Grant NOPASSWD only for the specific commands needed, not ALL.

sudo echo > file: Permission denied

🛡 Permissions & shell
bash: /etc/hosts: Permission denied
sudo echo 'x' > /etc/sysctl.d/99-custom.conf
bash: /etc/sysctl.d/99-custom.conf: Permission denied

What it means: The > redirect is done by your own shell, before sudo runs, so it has no root rights.

Common causes

  • Using sudo echo ... > file or sudo cat ... > file.

How to fix it

  1. Let a root process do the writing with tee:

    echo '127.0.0.1 myhost' | sudo tee -a /etc/hosts
    echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-custom.conf
  2. Or run the whole command in a root shell:

    sudo sh -c "echo 'vm.swappiness=10' > /etc/sysctl.d/99-custom.conf"

npm: EACCES: permission denied, mkdir '/usr/local/lib/node_modules'

🛡 Permissions & shell
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/pm2'
npm ERR! The operation was rejected by your operating system.

What it means: npm install -g tried to write to a system folder your user can't write to.

Common causes

  • Global installs go to /usr/local by default, which belongs to root.

How to fix it

  1. Use a Node version manager such as nvm (follow its install instructions); it keeps Node and global packages in your home folder:

    nvm install --lts
    npm install -g pm2
  2. Or point npm's global folder at your home:

    npm config set prefix ~/.npm-global
    echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc

Careful: Avoid sudo npm install -g and chmod 777 /usr/local; they leave root-owned files that break later installs.

💽 Disk & boot (11)

No space left on device

💽 Disk & boot
No space left on device
write error: No space left on device
ENOSPC: no space left on device

What it means: A write failed because the filesystem is full, or it has run out of inodes (file slots) even with space left.

Common causes

  • Logs, caches, old kernels, backups or Docker images filled the disk.
  • Millions of tiny files (sessions, mail queue, cache) used up the inodes.
  • A deleted file that a running process still holds open keeps its space in use.

How to fix it

  1. Check space and inodes:

    df -h
    df -i
  2. Find what's large, staying on one filesystem:

    sudo du -xh / --max-depth=2 2>/dev/null | sort -h | tail -n 20
  3. Find deleted-but-open files and restart the process holding them:

    sudo lsof -nP +L1 | head
  4. Shrink the systemd journal and clean package caches:

    sudo journalctl --vacuum-size=200M
    sudo apt clean

mount: wrong fs type, bad option, bad superblock

💽 Disk & boot
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/sdb1, missing codepage or helper program, or other error.

What it means: mount couldn't make sense of the device with the type or options you gave.

Common causes

  • The helper for that filesystem isn't installed (nfs-common, cifs-utils, ntfs-3g, exfatprogs).
  • Wrong device (the whole disk instead of a partition) or wrong -t type.
  • The filesystem is damaged, or it's an NTFS disk Windows left hibernated (Fast Startup).

How to fix it

  1. See what's really on the device:

    lsblk -f
    sudo blkid /dev/sdb1
  2. Install the matching helper (Debian/Ubuntu names):

    sudo apt install nfs-common cifs-utils ntfs-3g exfatprogs
  3. Read the kernel's detailed reason:

    sudo dmesg | tail -n 20
  4. For a hibernated NTFS disk, shut Windows down fully (or turn off Fast Startup) rather than forcing the mount.

umount: target is busy

💽 Disk & boot
umount: /mnt/data: target is busy.
umount: /mnt/data: device is busy.

What it means: Something is still using the filesystem, so it can't be unmounted safely.

Common causes

  • A shell is cd'd into it, or a process has files open there (an editor, a backup, a service).

How to fix it

  1. Find the processes using it:

    sudo lsof +f -- /mnt/data
    sudo fuser -vm /mnt/data
  2. Leave the directory, stop those processes, then unmount:

    cd /
    sudo umount /mnt/data

Careful: umount -l (lazy) hides the problem; the device stays in use. Find and stop the process instead.

Read-only file system

💽 Disk & boot
touch: cannot touch 'file': Read-only file system
EROFS: read-only file system

What it means: The filesystem is mounted read-only. If it was writable before, the kernel probably switched it after detecting errors.

Common causes

  • The kernel remounted the filesystem read-only after disk or filesystem errors (errors=remount-ro).
  • It's mounted ro on purpose (a container, snap, ISO, or ProtectSystem= in a systemd service).

How to fix it

  1. Look for disk errors first:

    sudo dmesg -T | grep -iE 'error|ext4|xfs|i/o' | tail -n 20
    findmnt -no OPTIONS /
  2. Check the disk's health:

    sudo smartctl -a /dev/sda
  3. If the filesystem needs repair, run fsck from a rescue boot with it unmounted. Only remount writable once it's healthy:

    sudo mount -o remount,rw /

UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY

💽 Disk & boot
/dev/sda1: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
	(i.e., without -a or -p options)

What it means: The automatic boot-time check found damage it won't fix on its own, and dropped you to a recovery shell.

Common causes

  • An unclean shutdown (power loss, hard reset).
  • A failing disk.

How to fix it

  1. From the recovery shell, repair the named filesystem (it must not be mounted):

    fsck -y /dev/sda1
  2. Reboot, then check the disk's health and back up important data:

    reboot
    sudo smartctl -H /dev/sda

Structure needs cleaning

💽 Disk & boot
cannot access 'file': Structure needs cleaning
EUCLEAN

What it means: The filesystem found corrupted metadata (common wording on ext4 and XFS).

Common causes

  • Unclean shutdown, failing disk or storage controller.

How to fix it

  1. Unmount it (or boot a rescue system for /) and repair:

    sudo umount /dev/sdb1
    sudo fsck -f /dev/sdb1
    sudo xfs_repair /dev/sdb1
  2. Check the disk itself:

    sudo smartctl -a /dev/sdb

Argument list too long

💽 Disk & boot
bash: /bin/rm: Argument list too long
-bash: /usr/bin/cp: Argument list too long

What it means: A wildcard such as * expanded to more file names than one command line can hold.

Common causes

  • A folder with tens or hundreds of thousands of files.

How to fix it

  1. Let find handle the files instead of the shell:

    find /path -maxdepth 1 -type f -name '*.log' -delete
  2. Or pass them in batches:

    find /path -maxdepth 1 -type f -name '*.jpg' -print0 | xargs -0 cp -t /dest/

Too many open files

💽 Disk & boot
Too many open files
socket: too many open files
EMFILE: too many open files

What it means: The process reached its limit of open files and sockets (often 1024 by default).

Common causes

  • A busy server (many connections) with the default limit.
  • A program that leaks file handles.

How to fix it

  1. See the limit and how many a process has open:

    ulimit -n
    ls /proc/<pid>/fd | wc -l
  2. For a systemd service, raise it in an override, then restart:

    sudo systemctl edit myapp
    # add:
    [Service]
    LimitNOFILE=65536
  3. If the count keeps climbing, the program leaks handles; raising the limit only delays the error.

Kernel panic: VFS: Unable to mount root fs

💽 Disk & boot
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

What it means: The kernel started but couldn't find or read the root filesystem.

Common causes

  • The initramfs for this kernel is missing or wasn't generated (often after an interrupted upgrade, or a full /boot).
  • The root device or UUID in the boot loader is wrong, or the disk driver isn't in the initramfs.

How to fix it

  1. Pick an older kernel from the boot menu (GRUB → Advanced options). Once booted, rebuild the initramfs and GRUB config (Debian/Ubuntu shown):

    sudo update-initramfs -u -k all
    sudo update-grub
  2. On RHEL-family systems:

    sudo dracut -f --regenerate-all
    sudo grub2-mkconfig -o /boot/grub2/grub.cfg
  3. Check that /boot has free space:

    df -h /boot

You are in emergency mode (bad fstab entry)

💽 Disk & boot
You are in emergency mode. After logging in, type "journalctl -xb" to view system logs
Give root password for maintenance
(or press Control-D to continue):
A start job is running for dev-disk-by\x2duuid-…device (1min 30s)

What it means: systemd couldn't mount something it was told is required at boot, so it stopped in emergency mode.

Common causes

  • A wrong UUID or device in /etc/fstab, or a disk that was removed.
  • A network share in fstab without _netdev and nofail.

How to fix it

  1. Log in, then find the mount that failed:

    journalctl -xb | grep -iE 'mount|fstab' | tail
    systemctl --failed
  2. Make / writable and fix the fstab line (comment it out, or correct the UUID from blkid):

    mount -o remount,rw /
    blkid
    nano /etc/fstab
  3. Add nofail to disks that may be absent so boot continues without them. Check the file before rebooting:

    UUID=…  /data  ext4  defaults,nofail  0  2
  4. systemctl daemon-reload
    mount -a

grub rescue> / error: no such partition

💽 Disk & boot
error: no such partition.
Entering rescue mode...
grub rescue>
error: unknown filesystem.

What it means: GRUB's first stage loaded, but it can't find the partition holding the rest of GRUB.

Common causes

  • Partitions were moved, resized or deleted (often by another OS installer).
  • The disk order changed.

How to fix it

  1. At the prompt, find the partition that holds /boot/grub:

    ls
    ls (hd0,gpt2)/
  2. Point GRUB at it and continue booting (use the partition you found):

    set root=(hd0,gpt2)
    set prefix=(hd0,gpt2)/boot/grub
    insmod normal
    normal
  3. Once booted, reinstall GRUB so it survives the next reboot (BIOS systems shown; on UEFI run sudo grub-install without a disk name):

    sudo grub-install /dev/sda
    sudo update-grub

⚙️ systemd (6)

Unit … .service not found

⚙️ systemd
Failed to start nginx.service: Unit nginx.service not found.
Unit foo.service could not be found.

What it means: systemd has no unit by that name.

Common causes

  • The software isn't installed, or its service has another name (ssh vs sshd, apache2 vs httpd, mysql vs mariadb).
  • You created a unit file but didn't run systemctl daemon-reload.
  • It's a user service (systemctl --user) or lives in an unusual folder.

How to fix it

  1. Search for the right name:

    systemctl list-unit-files | grep -i nginx
  2. After adding or editing a unit file, reload systemd:

    sudo systemctl daemon-reload
    sudo systemctl start myapp

Job for … failed because the control process exited with error code

⚙️ systemd
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.

What it means: The service's start command failed. The message itself is generic; the reason is in the service's log.

Common causes

  • A config file error, a port already in use, missing files or permissions, or a wrong path in the unit file.

How to fix it

  1. Read the service's own error messages:

    systemctl status nginx.service
    journalctl -xeu nginx.service --no-pager | tail -n 40
  2. Many services can check their config without starting:

    sudo nginx -t
    sudo apachectl configtest
    sudo sshd -t
    sudo named-checkconf

status=203/EXEC

⚙️ systemd
Main process exited, code=exited, status=203/EXEC
Failed to locate executable /opt/app/run.sh: No such file or directory
Failed to execute /opt/app/run.sh: Permission denied

What it means: systemd couldn't run the program in ExecStart at all, before your program even began.

Common causes

  • The path is wrong or not absolute, or the file doesn't exist.
  • The file isn't executable, or a script has no #! line or has Windows line endings.
  • SELinux blocks running it from that location (for example from a home folder).

How to fix it

  1. Check the path and permissions systemd sees:

    systemctl cat myapp
    ls -l /opt/app/run.sh
    head -1 /opt/app/run.sh
  2. Make it executable and fix line endings:

    sudo chmod +x /opt/app/run.sh
    sudo sed -i 's/\r$//' /opt/app/run.sh
  3. Use a full path to the interpreter if needed: ExecStart=/usr/bin/python3 /opt/app/app.py

Start request repeated too quickly

⚙️ systemd
myapp.service: Start request repeated too quickly.
myapp.service: Failed with result 'start-limit-hit'.

What it means: The service crashed and restarted too many times in a short window, so systemd stopped trying.

Common causes

  • The service fails right after starting (bad config, missing dependency), and Restart= keeps relaunching it.

How to fix it

  1. Find the first real error before the restarts:

    journalctl -u myapp -b --no-pager | head -n 60
  2. After fixing it, clear the failure counter and start again:

    sudo systemctl reset-failed myapp
    sudo systemctl start myapp

System has not been booted with systemd / Failed to connect to bus

⚙️ systemd
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Failed to connect to bus: No such file or directory

What it means: systemctl needs systemd running as PID 1, and it isn't here.

Common causes

  • Inside a Docker container (containers normally run one process, not systemd).
  • WSL without systemd enabled.
  • systemctl --user in a session without a user bus (su, sudo, cron).

How to fix it

  1. In a container, run the program directly instead of as a service (it should be the container's main process).

  2. In WSL, enable systemd in /etc/wsl.conf, then run wsl --shutdown from Windows:

    [boot]
    systemd=true
  3. For user services over SSH, enable lingering and use a proper login session:

    sudo loginctl enable-linger $USER

The unit file changed on disk. Run systemctl daemon-reload

⚙️ systemd
Warning: The unit file, source configuration file or drop-ins of myapp.service changed on disk. Run 'systemctl daemon-reload' to reload units.

What it means: You edited a unit file, and systemd is still using the old version it loaded earlier.

Common causes

  • Editing files in /etc/systemd/system/ by hand.

How to fix it

  1. Reload, then restart the service:

    sudo systemctl daemon-reload
    sudo systemctl restart myapp
  2. Tip: sudo systemctl edit myapp creates an override file and reloads for you.

🧠 Memory (3)

Out of memory: Killed process

🧠 Memory
Out of memory: Killed process 1234 (java) total-vm:8123456kB, anon-rss:6543210kB
oom-kill:constraint=CONSTRAINT_NONE
Killed

What it means: The system ran out of memory, so the kernel's OOM killer ended the process it judged the best one to sacrifice.

Common causes

  • A memory leak or a process that grew bigger than the machine.
  • Too many services for the RAM, and no swap.
  • A container or cgroup memory limit (then it's that limit, not the whole machine).

How to fix it

  1. Confirm and see what was killed:

    sudo dmesg -T | grep -iE 'killed process|oom'
    journalctl -k | grep -i oom
  2. See current memory use per process:

    free -h
    ps aux --sort=-%mem | head
  3. Fix the cause (limit heap sizes, add RAM), or add swap as a buffer:

    sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
    sudo mkswap /swapfile && sudo swapon /swapfile

fork: Resource temporarily unavailable

🧠 Memory
bash: fork: retry: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable

What it means: A new process couldn't be created, usually because a process limit was reached.

Common causes

  • The user hit their maximum process count (ulimit -u).
  • A service hit systemd's TasksMax limit, or the system-wide PID limit was reached (a fork bomb or a leak).

How to fix it

  1. Check the limits and how many processes the user runs:

    ulimit -u
    ps -u $USER --no-headers | wc -l
    cat /proc/sys/kernel/pid_max
  2. For a systemd service, check and raise TasksMax:

    systemctl show myapp -p TasksMax -p TasksCurrent

Cannot allocate memory

🧠 Memory
fork: Cannot allocate memory
ENOMEM: Cannot allocate memory

What it means: The kernel couldn't hand out the memory a program asked for.

Common causes

  • Real memory exhaustion, or overcommit settings that refuse large requests.
  • Hitting the process or thread limit can also show up this way.

How to fix it

  1. Check memory and overcommit settings:

    free -h
    sysctl vm.overcommit_memory vm.overcommit_ratio
  2. Find the biggest memory users:

    ps aux --sort=-%mem | head

⏰ Cron (2)

(CRON) info (No MTA installed, discarding output)

⏰ Cron
(CRON) info (No MTA installed, discarding output)

What it means: Your cron job printed something, cron tried to email it to you, and there's no mail system, so the output was thrown away.

Common causes

  • Nothing is wrong with cron itself. The job wrote output, and that output may include its error messages.

How to fix it

  1. Send the job's output to a log file so you can read it:

    */5 * * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
  2. Or set MAILTO="" at the top of the crontab to drop mail entirely (you'll lose error output).

crontab: errors in crontab file, can't install

⏰ Cron
"/tmp/crontab.abc123":3: bad minute
errors in crontab file, can't install.
bad day-of-week

What it means: A line in your crontab doesn't follow the five-field schedule format, so crontab rejected the whole file.

Common causes

  • Six fields (seconds) copied from Quartz or another scheduler.
  • Out-of-range values, or a username field in a personal crontab (only /etc/crontab has one).

How to fix it

  1. Check each schedule with the Cron Visualizer, then edit again:

    crontab -e
  2. The number after the file name (:3:) is the line to look at.

🌿 Git (5)

detected dubious ownership in repository

🌿 Git
fatal: detected dubious ownership in repository at '/srv/app'
To add an exception for this directory, call:

	git config --global --add safe.directory /srv/app

What it means: Git refuses to work in a repository owned by another user, to protect you from malicious config in it.

Common causes

  • The repo was cloned by root or another user, or copied from a different machine or a mounted drive.
  • Running git under sudo, in a container, or from a CI runner with a different user.

How to fix it

  1. Best: make the repo owned by the user who uses it:

    sudo chown -R $USER: /srv/app
  2. Or trust that one folder for your user:

    git config --global --add safe.directory /srv/app

Careful: Avoid safe.directory '*'; it switches the protection off everywhere.

Updates were rejected because the remote contains work that you do not have

🌿 Git
! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the remote contains work that you do not have locally.

What it means: Someone (or you, elsewhere) pushed commits you don't have yet, so your push would overwrite them.

Common causes

  • New commits on the remote branch.

How to fix it

  1. Bring their work in, then push:

    git pull --rebase origin main
    git push
  2. If there are conflicts, fix the files, then continue:

    git add <file>
    git rebase --continue

Careful: Don't git push --force on a shared branch; it deletes other people's commits. If you must, use --force-with-lease.

refusing to merge unrelated histories

🌿 Git
fatal: refusing to merge unrelated histories

What it means: The two branches have no commit in common, so Git won't merge them by default.

Common causes

  • You created a repo on GitHub with a README and also ran git init locally with your own first commit.

How to fix it

  1. If you're sure both histories belong together, allow it once:

    git pull origin main --allow-unrelated-histories

Your local changes would be overwritten by merge

🌿 Git
error: Your local changes to the following files would be overwritten by merge:
	config.php
Please commit your changes or stash them before you merge.

What it means: You edited files that the pull or checkout also changes, and Git won't throw your edits away.

Common causes

  • Uncommitted edits, often to config files on a server.

How to fix it

  1. Keep your changes aside, pull, then put them back:

    git stash
    git pull
    git stash pop
  2. If you don't want your local edits (they will be lost):

    git restore config.php

fatal: not a git repository

🌿 Git
fatal: not a git repository (or any of the parent directories): .git

What it means: You're running git in a folder that isn't inside a repository.

Common causes

  • Wrong directory, or the .git folder was deleted or not copied.

How to fix it

  1. Check where you are and go to the repo's folder:

    pwd
    ls -a
    cd /path/to/repo

🪟 Windows (7)

Running scripts is disabled on this system

🪟 Windows
File C:\scripts\setup.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies
PowerShell says "execution of scripts is disabled on this system."

What it means: PowerShell's execution policy blocks running .ps1 scripts. Windows client editions default to Restricted.

Common causes

  • The default policy on Windows 10/11 is Restricted.
  • A downloaded script is marked as coming from the internet.

How to fix it

  1. Allow local scripts and signed downloaded ones, for your user only:

    Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
  2. Check the policy at every level:

    Get-ExecutionPolicy -List
  3. For a script you trust that was downloaded, remove the internet mark:

    Unblock-File .\setup.ps1
  4. For a single run without changing the policy:

    powershell -ExecutionPolicy Bypass -File .\setup.ps1

Careful: Don't set Unrestricted for the whole machine. Group Policy may also override your setting.

The term '…' is not recognized as the name of a cmdlet

🪟 Windows
The term 'kubectl' is not recognized as the name of a cmdlet, function, script file, or operable program.

What it means: PowerShell (or cmd) can't find a command by that name.

Common causes

  • The program isn't installed, or its folder isn't in PATH.
  • A module isn't imported or installed (for example Get-ADUser needs RSAT).
  • Running a script in the current folder without .\ in front.

How to fix it

  1. Run a script from the current folder:

    .\script.ps1
  2. Check where Windows finds it and what PATH contains:

    Get-Command kubectl
    $env:Path -split ';'
  3. For AD cmdlets, install RSAT and load the module:

    Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
    Import-Module ActiveDirectory

The trust relationship between this workstation and the primary domain failed

🪟 Windows
The trust relationship between this workstation and the primary domain failed.

What it means: The computer's secret password with Active Directory no longer matches, so domain logins fail.

Common causes

  • The PC was restored from an old snapshot or image.
  • The computer account was reset or deleted in AD, or two PCs share a name.

How to fix it

  1. Log in with a local admin account, then repair the secure channel (prompts for domain admin credentials):

    Test-ComputerSecureChannel -Repair -Credential (Get-Credential)
  2. Or reset the machine password:

    Reset-ComputerMachinePassword -Credential (Get-Credential)
  3. If that fails, remove the PC from the domain and join it again.

The RPC server is unavailable

🪟 Windows
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

What it means: The remote Windows machine couldn't be reached over RPC (used by WMI, remote management and AD tools).

Common causes

  • The machine is off, the name resolves to the wrong IP, or a firewall blocks RPC (port 135 plus dynamic ports).
  • The Remote Procedure Call or WMI services are stopped.

How to fix it

  1. Check name resolution and that the endpoint mapper port answers:

    Resolve-DnsName pc01
    Test-NetConnection pc01 -Port 135
  2. Allow the remote-management firewall rules on the target:

    Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)"

Access is denied (Windows)

🪟 Windows
Access is denied.
Access to the path 'C:\Program Files\App\config.json' is denied.
System error 5 has occurred.

What it means: Your account doesn't have the rights for that action, or the window isn't running with administrator rights.

Common causes

  • The command needs an elevated prompt (User Account Control).
  • NTFS permissions on the file or folder don't include you.
  • The file is locked by another program, or antivirus blocked it.

How to fix it

  1. Open PowerShell or cmd with Run as administrator and try again.

  2. Check the file's permissions:

    icacls "C:\Program Files\App\config.json"

An Active Directory Domain Controller for the domain could not be contacted

🪟 Windows
An Active Directory Domain Controller (AD DC) for the domain "corp.example.com" could not be contacted.
The specified domain either does not exist or could not be contacted.

What it means: The PC couldn't find a domain controller for that domain, which almost always means a DNS problem.

Common causes

  • The PC uses a public or router DNS server instead of the domain's DNS servers.
  • Firewall or network blocks to the DCs, or a typo in the domain name.

How to fix it

  1. Point the network adapter's DNS at your domain controllers, then test that the DC records resolve:

    Resolve-DnsName -Type SRV _ldap._tcp.dc._msdcs.corp.example.com
  2. Test reaching a DC:

    nltest /dsgetdc:corp.example.com
    Test-NetConnection dc01.corp.example.com -Port 389

WinRM cannot complete the operation

🪟 Windows
Connecting to remote server srv01 failed with the following error message : WinRM cannot complete the operation. Verify that the specified computer name is valid, that the computer is accessible over the network, and that a firewall exception for the WinRM service is enabled

What it means: PowerShell remoting couldn't reach the WinRM service on the other machine.

Common causes

  • Remoting isn't enabled on the target.
  • Firewall blocks port 5985 (HTTP) or 5986 (HTTPS).
  • Outside a domain, the target isn't in your TrustedHosts list.

How to fix it

  1. On the target (as administrator), enable remoting:

    Enable-PSRemoting -Force
  2. From your machine, test the port and the service:

    Test-NetConnection srv01 -Port 5985
    Test-WSMan srv01
  3. For non-domain machines, add the target to TrustedHosts:

    Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'srv01' -Concatenate

☸️ Kubernetes (5)

CrashLoopBackOff

☸️ Kubernetes
CrashLoopBackOff
Back-off restarting failed container

What it means: The container keeps starting and crashing, so Kubernetes waits longer and longer between restarts.

Common causes

  • The app exits on startup: bad config, missing environment variable or secret, can't reach its database.
  • A failing liveness probe kills it.
  • It's out of memory (look for OOMKilled).

How to fix it

  1. Read the logs of the crashed attempt, not just the current one:

    kubectl logs <pod> --previous
  2. See the exit code, reason and events:

    kubectl describe pod <pod>

ImagePullBackOff / ErrImagePull

☸️ Kubernetes
ImagePullBackOff
ErrImagePull
Failed to pull image "myapp:latest": rpc error: code = NotFound

What it means: The node can't download the container image.

Common causes

  • Wrong image name or tag.
  • A private registry and no imagePullSecrets.
  • Docker Hub rate limits, or the node can't reach the registry.

How to fix it

  1. The events show the exact pull error:

    kubectl describe pod <pod> | tail -n 20
  2. For a private registry, create a pull secret and reference it in the pod spec:

    kubectl create secret docker-registry regcred --docker-server=ghcr.io --docker-username=USER --docker-password=TOKEN

The connection to the server localhost:8080 was refused

☸️ Kubernetes
The connection to the server localhost:8080 was refused - did you specify the right host or port?

What it means: kubectl has no kubeconfig, so it falls back to localhost:8080, where nothing is listening.

Common causes

  • ~/.kube/config is missing (common right after kubeadm, or when running as a different user).
  • KUBECONFIG points to a file that doesn't exist.

How to fix it

  1. After kubeadm, copy the admin config for your user:

    mkdir -p ~/.kube
    sudo cp /etc/kubernetes/admin.conf ~/.kube/config
    sudo chown $(id -u):$(id -g) ~/.kube/config
  2. For k3s:

    export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
  3. Check the active context:

    kubectl config current-context

Pod Pending: Insufficient cpu / memory

☸️ Kubernetes
0/3 nodes are available: 3 Insufficient cpu.
0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }

What it means: The scheduler can't find a node that fits the pod, so it stays Pending.

Common causes

  • Resource requests bigger than any node's free capacity.
  • Taints the pod doesn't tolerate (on a one-node cluster, the control-plane taint).
  • Node selectors or affinity that no node matches, or an unbound PersistentVolumeClaim.

How to fix it

  1. Read the scheduler's reason:

    kubectl describe pod <pod> | grep -A5 Events
  2. Compare requests with what's free on the nodes:

    kubectl describe nodes | grep -A6 'Allocated resources'
  3. On a single-node test cluster, allow pods on the control plane:

    kubectl taint nodes --all node-role.kubernetes.io/control-plane-

CreateContainerConfigError

☸️ Kubernetes
CreateContainerConfigError
Error: secret "db-pass" not found
Error: configmap "app-config" not found

What it means: Kubernetes can't build the container's configuration because something it references is missing.

Common causes

  • A Secret or ConfigMap (or a key inside it) named in the pod spec doesn't exist in that namespace.

How to fix it

  1. See what's missing, then check it exists in the same namespace:

    kubectl describe pod <pod>
    kubectl get secret,configmap -n <namespace>

🗄 Databases (7)

Access denied for user 'root'@'localhost'

🗄 Databases
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

What it means: MySQL or MariaDB rejected the login for that user and host.

Common causes

  • Wrong password, or the account exists only for another host ('app'@'%' vs 'app'@'localhost').
  • Error 1698: root uses socket authentication on Debian/Ubuntu, so it only works as the system root user.

How to fix it

  1. For socket-authenticated root, log in through sudo:

    sudo mysql
  2. Create a separate account for your app instead of using root:

    CREATE USER 'app'@'localhost' IDENTIFIED BY 'strong-password';
    GRANT ALL ON appdb.* TO 'app'@'localhost';
  3. List which user and host combinations exist:

    SELECT user, host, plugin FROM mysql.user;

Can't connect to local MySQL server through socket

🗄 Databases
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

What it means: The client looked for the server's socket file and didn't find a running server there.

Common causes

  • The MySQL/MariaDB service isn't running (often it failed to start: disk full, bad config).
  • Client and server use different socket paths.

How to fix it

  1. Check and start the service, then read why it stopped:

    sudo systemctl status mysql mariadb
    sudo journalctl -u mysql -u mariadb -n 50
  2. Or connect over TCP instead of the socket:

    mysql -h 127.0.0.1 -u app -p

Peer authentication failed for user

🗄 Databases
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  Peer authentication failed for user "app"
FATAL:  password authentication failed for user "app"

What it means: PostgreSQL rejected the login because of the method set in pg_hba.conf.

Common causes

  • Peer authentication: local socket logins must come from the OS user with the same name.
  • A wrong password, or the role has no password set.

How to fix it

  1. Connect over TCP, which normally uses password authentication:

    psql -h 127.0.0.1 -U app appdb
  2. Or switch to the postgres OS user to manage roles:

    sudo -u postgres psql
    ALTER USER app WITH PASSWORD 'strong-password';
  3. If you change pg_hba.conf, reload PostgreSQL:

    sudo systemctl reload postgresql

could not connect to server: Connection refused (PostgreSQL)

🗄 Databases
psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?

What it means: Nothing accepted the connection on PostgreSQL's port.

Common causes

  • PostgreSQL isn't running.
  • It listens only on localhost (listen_addresses), and you connect from another machine.
  • A firewall blocks port 5432.

How to fix it

  1. Check the service and where it listens:

    sudo systemctl status postgresql
    sudo ss -tlnp | grep 5432
  2. To accept remote connections, set listen_addresses = '*' in postgresql.conf, add a host line in pg_hba.conf, then restart.

Too many connections (MySQL)

🗄 Databases
ERROR 1040 (HY000): Too many connections
SQLSTATE[HY000] [1040] Too many connections

What it means: MySQL reached max_connections, so new clients are refused.

Common causes

  • The app leaks connections (opens and doesn't close), or a traffic spike.
  • Slow queries hold connections open, so they pile up.

How to fix it

  1. See who is connected and what they run (MySQL keeps one slot for an admin):

    sudo mysql -e 'SHOW PROCESSLIST;'
    sudo mysql -e "SHOW VARIABLES LIKE 'max_connections';"
  2. Raise the limit for now if the server has memory to spare, and fix the app's connection pool:

    SET GLOBAL max_connections = 300;

FATAL: role "…" does not exist

🗄 Databases
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  role "alice" does not exist

What it means: psql logged in as a PostgreSQL role with your OS username, and no such role exists.

Common causes

  • psql defaults to a role named like your Linux user.

How to fix it

  1. Create a role for yourself, or connect as postgres:

    sudo -u postgres createuser --interactive alice
    sudo -u postgres psql

MISCONF Redis is configured to save RDB snapshots

🗄 Databases
MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. Commands that may modify the data set are disabled

What it means: Redis couldn't write its snapshot to disk, so it stopped accepting writes to protect your data.

Common causes

  • The disk is full, or Redis can't write to its dir folder.
  • The background save was killed for lack of memory (vm.overcommit_memory is 0).

How to fix it

  1. Check the reason Redis reports and free space:

    redis-cli INFO persistence | grep -i rdb_last_bgsave
    df -h
  2. Allow the kernel to overcommit memory for the forked save, as Redis recommends:

    echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/99-redis.conf
    sudo sysctl -p /etc/sysctl.d/99-redis.conf

Careful: Don't just set stop-writes-on-bgsave-error no; that hides the fact that your data isn't being saved.

These fixes are general guidance. Check them against your own system before running commands as root, and keep a backup before changing disks, boot settings or packages.