Matching happens as you type. Paths, hostnames and numbers don't need to match.
ssh -v log, use SSH DoctorWARNING: 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)).
chmod -R 755 ~/.ssh or similar.Make the key readable by you only, and the folder private:
chmod 700 ~/.ssh chmod 600 ~/.ssh/id_rsa
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
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).
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.
~/.ssh/authorized_keys on the server, or it's in the wrong user's account.ssh -v).ssh host when the account is ubuntu, ec2-user or admin.~ or ~/.ssh is writable by others, so sshd ignores authorized_keys (StrictModes).See which keys are offered and why each is rejected:
ssh -v user@host
Use a specific key and username:
ssh -i ~/.ssh/id_ed25519 user@host
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
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
Check the server log for the real reason:
sudo journalctl -u ssh -u sshd --since '10 min ago'
For GitHub or GitLab, add the public key to your account settings, then test:
ssh -T git@github.com
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ 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.
Confirm the new fingerprint with whoever runs the server (or from its console):
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Then remove only the old entry for that host and connect again:
ssh-keygen -R hostname ssh-keygen -R 192.0.2.10
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.
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.
known_hosts yet and SSH can't ask you (a script, cron job, CI runner or git without a terminal).known_hosts.Connect once by hand as the same user that runs the job, check the fingerprint and accept it:
ssh user@host
Or add the host key ahead of time (check it against a trusted source):
ssh-keyscan -H host >> ~/.ssh/known_hosts
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.
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.
Best fix: update the server or its firmware so it offers modern algorithms (ed25519, rsa-sha2-256/512, curve25519).
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
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
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.
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.
Start an agent in the current shell and add your key:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519
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 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.
Port in /etc/ssh/sshd_config).On the server (console), check that sshd is running and which port it uses:
sudo systemctl status ssh sshd sudo ss -tlnp | grep ssh
Install and start it if missing (Debian/Ubuntu shown):
sudo apt install openssh-server sudo systemctl enable --now ssh
If it uses another port, connect to that port:
ssh -p 2222 user@host
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.
Check that the host answers at all and where the path stops:
ping -c 3 host traceroute host
Test the port directly:
nc -vz host 22
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
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.
ssh-agent, and the right one is far down the list.Tell SSH to use only the key you name:
ssh -o IdentitiesOnly=yes -i ~/.ssh/server_key user@host
Make it permanent in ~/.ssh/config:
Host myserver
HostName 192.0.2.10
User admin
IdentityFile ~/.ssh/server_key
IdentitiesOnly yeskex_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.
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).On the server, read the sshd log at the time you connected:
sudo journalctl -u ssh -u sshd -n 50
Check whether fail2ban banned you, and unban:
sudo fail2ban-client status sshd sudo fail2ban-client set sshd unbanip 203.0.113.5
Check that the sshd configuration is valid:
sudo sshd -t
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.
Give it back to your user and make it private:
chown $USER:$USER ~/.ssh/config chmod 600 ~/.ssh/config
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.
.ppk format, not OpenSSH format..pub) instead of the private key.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
Fix Windows line endings and make sure the file ends with a newline:
sed -i 's/\r$//' ~/.ssh/id_rsa echo >> ~/.ssh/id_rsa
Check that the key is readable (prints its public half):
ssh-keygen -y -f ~/.ssh/id_rsa
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.
unattended-upgrades) are running, very often right after boot.See what holds the lock, then wait for it to finish (usually a few minutes):
ps aux | grep -E 'apt|dpkg' | grep -v grep
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 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.
apt update first.universe).Refresh the package lists, then try again:
sudo apt update sudo apt install nginx
Search for the right name:
apt search nginx apt-cache policy nginx
On Ubuntu, enable the universe repository if the package lives there:
sudo add-apt-repository universe sudo apt update
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.
apt-mark hold).See the full chain of what conflicts:
sudo apt install -f sudo apt install <package> --dry-run
List held packages and release any you didn't mean to hold:
apt-mark showhold sudo apt-mark unhold <package>
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.
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.
Finish configuring the half-installed packages, then repair anything still broken:
sudo dpkg --configure -a sudo apt install -f
Run long upgrades inside tmux or screen so a dropped SSH session can't interrupt them.
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.
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
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.
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.
Check the clock and turn on time sync:
timedatectl sudo timedatectl set-ntp true
On WSL, restart WSL from Windows to resync the clock:
wsl --shutdown
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).
Find the file that adds the repository:
grep -r 'ppa.launchpad.net/foo' /etc/apt/sources.list /etc/apt/sources.list.d/
Remove or comment out that repository, then update:
sudo add-apt-repository --remove ppa:foo/bar sudo apt update
For an end-of-life release, upgrade to a supported release (or point the sources at old-releases.ubuntu.com only as a stopgap).
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.
Clear the cached lists and try again:
sudo rm -rf /var/lib/apt/lists/* sudo apt clean sudo apt update
If it persists, switch to a different mirror in your sources, or bypass the proxy.
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.
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
If one package keeps failing, reinstall it to see its own error:
sudo apt install --reinstall <package>
Check free space:
df -h /var /
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.
Search, and find which package provides a command:
dnf search htop dnf provides '*/bin/htop'
Enable EPEL on RHEL-compatible systems:
sudo dnf install epel-release
Refresh metadata:
sudo dnf clean all sudo dnf makecache
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.
Import the vendor's key from the URL in their docs, then retry:
sudo rpm --import https://example.com/RPM-GPG-KEY-example
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.
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.
Test name resolution and access first:
getent hosts mirrorlist.centos.org curl -I https://dl.fedoraproject.org
For an end-of-life CentOS, move to a supported distro (Rocky, AlmaLinux, RHEL); pointing repos at vault.centos.org only buys time.
Disable a broken third-party repo for one run:
sudo dnf --disablerepo=<repo-id> upgrade
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.
dnf-automatic, PackageKit or GNOME Software is updating in the background.See what it is and let it finish:
ps -fp 1234
If it's hung, stop it, then check the database:
sudo kill 1234 sudo rpm --rebuilddb
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.
Use a virtual environment for your project:
python3 -m venv .venv . .venv/bin/activate pip install requests
For command-line tools, use pipx:
sudo apt install pipx pipx install httpie
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. 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.
apt is meant for people at a terminal.In scripts, use the stable tools instead:
apt-get install -y nginx apt-cache policy nginx dpkg-query -W nginx
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.
DOCKER_HOST or the docker context points somewhere else.Start Docker and make it start at boot:
sudo systemctl enable --now docker sudo systemctl status docker
If it won't start, read why:
sudo journalctl -u docker -n 50
Check where the CLI is pointing:
docker context ls echo $DOCKER_HOST
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.
docker group, or you were added but haven't logged in again.Add yourself to the docker group, then start a new login session:
sudo usermod -aG docker $USER newgrp docker
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.
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.
Find what uses the port:
docker ps --filter publish=80 sudo ss -tlnp | grep ':80 '
Stop the old container, or publish on a different host port:
docker stop <container> docker run -p 8081:80 nginx
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.
See what Docker is using:
docker system df df -h /var/lib/docker
Remove unused data (asks first; add --volumes only if you're sure the volumes are unused):
docker system prune docker builder prune
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 /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.
#!/bin/sh first line, or saved with Windows line endings.Check the image's architecture against the host:
docker image inspect <image> --format '{{.Os}}/{{.Architecture}}'
uname -mBuild for the target platform (or both):
docker buildx build --platform linux/amd64,linux/arm64 -t myimage --push .
For scripts, add a shebang and convert line endings:
sed -i 's/\r$//' docker-entrypoint.sh
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.
Check local images and the exact name:
docker images | grep myapp
Log in to the right registry, then pull with the full name:
docker login ghcr.io docker pull ghcr.io/owner/myapp:1.2
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.
Log in, which raises the limit:
docker login
Use a pull-through cache or mirror the images you depend on into your own registry.
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.
bash.Use the shell the image has:
docker exec -it <container> sh
Check the image's configured command:
docker image inspect <image> --format '{{.Config.Entrypoint}} {{.Config.Cmd}}'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.
docker run --name twice; the first container is stopped but not removed.Remove the old one (or start it instead):
docker rm -f web docker start web
Use --rm for throwaway containers so they're removed when they stop.
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.
--memory, Compose mem_limit, Kubernetes limits).docker kill or the stop timeout expired.Check whether memory was the cause:
docker inspect <container> --format '{{.State.OOMKilled}}'
dmesg -T | grep -i 'killed process'Give it more memory, or find why it uses so much:
docker stats docker run --memory 1g myimage
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.
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
If you run the server, serve the full chain: in nginx use the fullchain.pem file, in Apache add the intermediate to SSLCertificateFile.
Update the client's CA certificates:
sudo apt install --reinstall ca-certificates sudo update-ca-certificates
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.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.
certifi bundle is out of date, or the server is missing its intermediate certificate.On macOS (python.org installer), run the certificate installer that ships with Python (use your version number):
/Applications/Python\ 3.12/Install\ Certificates.command
Update certifi:
python3 -m pip install --upgrade certifi
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.
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.
Check the dates the server sends:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
Check the client's clock:
date timedatectl
For Let's Encrypt, test and fix renewal, then reload the web server:
sudo certbot renew --dry-run sudo systemctl reload nginx
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.
Trust the CA properly on the client (Debian/Ubuntu shown):
sudo cp my-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
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
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.
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.
www.example.com but not example.com (or the reverse).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
Reissue the certificate with every name you use (Let's Encrypt shown):
sudo certbot --nginx -d example.com -d www.example.com
Connect using a name that's on the certificate.
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.
cacerts.Import the CA into the JDK's truststore (default password changeit):
sudo keytool -importcert -alias corp-ca -file corp-ca.crt -cacerts -storepass changeit
Or update the JDK. If you run the server, make it send the full chain.
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).
https:// pointed at a port that serves plain HTTP (for example https://host:80 or an app port).listen 443; instead of listen 443 ssl;).Test what the port speaks:
curl -v http://host:443/ openssl s_client -connect host:443
In nginx, make sure the listener has ssl:
listen 443 ssl; ssl_certificate /etc/ssl/fullchain.pem; ssl_certificate_key /etc/ssl/privkey.pem;
In Apache, enable the SSL module and site:
sudo a2enmod ssl sudo a2ensite default-ssl sudo systemctl reload apache2
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.
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
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 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.
.cer and .der files from Windows.Look at the start of the file:
head -c 64 cert.cer | xxd | head -3
Convert DER to PEM:
openssl x509 -inform der -in cert.cer -out cert.pem
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
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.
Check the domain points here (both IPv4 and IPv6):
dig +short A example.com dig +short AAAA example.com curl -4 ifconfig.me
Make sure port 80 is open, then try a dry run:
sudo ufw allow 80/tcp sudo certbot renew --dry-run
Behind a CDN or for wildcard certificates, use the DNS-01 challenge with your DNS provider's plugin instead.
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.
Require all granted for that directory (Apache 2.4 denies by default outside the DocumentRoot).www-data or apache) can't read the files, or can't enter one of the parent folders.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
Allow access to the directory in the site config, then reload:
<Directory /srv/www/site>
Require all granted
</Directory>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
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.
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.
ServerName is set.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
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
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.
listen lines for the same port with conflicting options.See who holds the port:
sudo ss -tlnp | grep -E ':(80|443) '
Stop and disable the one you don't want:
sudo systemctl disable --now apache2
Validate the config and start again:
sudo nginx -t sudo systemctl restart nginx
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.
proxy_pass or fastcgi_pass address is wrong (for example a different PHP version's socket).Read the nginx error log; it names the upstream and the reason:
sudo tail -n 30 /var/log/nginx/error.log
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/
Test the backend directly from the server:
curl -v http://127.0.0.1:3000/
On SELinux systems, allow nginx to make network connections:
sudo setsebool -P httpd_can_network_connect 1
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).
Find what's slow in the backend logs first; raising timeouts only hides it.
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;
}For PHP-FPM, the matching setting is fastcgi_read_timeout, plus PHP's own max_execution_time.
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.
client_max_body_size isn't set (1 MB default).Raise the limit in the http, server or location block, then reload:
client_max_body_size 50m;
For PHP apps, raise PHP's limits too (upload_max_filesize and post_max_size in php.ini).
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.
index.html (or index.php) in that folder, or the index directive doesn't list it.index.php isn't in the index line.13: Permission denied).Make sure the index file exists and is listed:
index index.html index.php;
For permission errors, check every folder on the path:
namei -l /var/www/html/index.html
Only if you really want a file listing, turn it on for that location: autoindex on;
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.
Raise the bucket size inside the http block, test and reload:
http {
server_names_hash_bucket_size 128;
}sudo nginx -t && sudo systemctl reload nginx
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.
Set-Cookie headers, often from login or session data.Enlarge the proxy buffers for that site:
proxy_buffer_size 16k; proxy_buffers 8 16k; proxy_busy_buffers_size 32k;
For PHP-FPM, use the fastcgi_ versions of the same settings.
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.
; or }, or a directive in the wrong block.Test the config and read the first error it reports:
sudo nginx -t
Show the full merged config to find the line:
sudo nginx -T | less
Only reload once the test passes:
sudo nginx -t && sudo systemctl reload nginx
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.
RewriteEngine needs mod_rewrite).Test the configuration:
sudo apachectl configtest
Enable the missing module (Debian/Ubuntu), then reload:
sudo a2enmod rewrite sudo systemctl reload apache2
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.
See the redirect chain:
curl -sIL http://example.com | grep -iE '^(HTTP|location)'
Behind a proxy, redirect based on the forwarded protocol, or use full (strict) TLS between the CDN and your server.
Make the app's configured URL match the real public address.
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).
127.0.0.1 while you connect from another machine (or the reverse).localhost means the container itself, not the host.On the server, check what is listening and on which address:
sudo ss -tlnp
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.
From a container, reach a service on the host via host.docker.internal (Docker Desktop) or the host's IP.
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".
icmp-host-prohibited (common on RHEL-family).Check your routes and whether the host answers:
ip route get 192.0.2.10 ping -c 3 192.0.2.10
On a RHEL-family target, open the port in firewalld:
sudo firewall-cmd --add-port=8080/tcp --permanent sudo firewall-cmd --reload
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).
/etc/resolv.conf was overwritten or points to a resolver that isn't running (WSL, containers, systemd-resolved).Tell DNS problems from network problems:
ping -c 2 1.1.1.1 getent hosts example.com
Check which DNS servers are in use:
resolvectl status cat /etc/resolv.conf
Query a public resolver directly to see if the name exists:
dig @1.1.1.1 example.com +short
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.
Check addresses and the default route:
ip addr ip route
Bring the connection up again (NetworkManager shown):
nmcli connection show sudo nmcli connection up <name>
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.
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 (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.
.bashrc), which corrupts the stream.Check rsync exists on the remote side:
ssh user@host 'which rsync'
Make sure a non-interactive SSH session prints nothing:
ssh user@host true | wc -c
Run with more detail to see where it fails:
rsync -avv --progress src/ user@host:/dest/
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.
Find the process on the port, then stop it:
sudo ss -tlnp 'sport = :3000' sudo lsof -i :3000
Or start the app on another port.
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.
sudo on Debian/Ubuntu, wheel on RHEL, Fedora and Arch.As root (or another admin), add the user to the right group:
usermod -aG sudo alice usermod -aG wheel alice
The user must log out and in again. Check with:
groups alice
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 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.
/etc/hosts.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
-bash: ./deploy.sh: Permission denied
What it means: The shell can't run the file as a program.
noexec (common for /tmp and some home or USB mounts).Make it executable, or run it through the interpreter:
chmod +x script.sh ./script.sh bash script.sh
Check for noexec on that mount:
findmnt -no OPTIONS --target ./script.sh
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.
Convert the file to Unix line endings:
sed -i 's/\r$//' script.sh # or: dos2unix script.sh
Stop Git converting shell scripts by adding a .gitattributes file to the repo:
*.sh text eol=lf
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.
PATH (for example ~/.local/bin, /usr/local/go/bin or /snap/bin).secure_path).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
If it's installed somewhere, add that folder to PATH in ~/.bashrc:
export PATH="$HOME/.local/bin:$PATH"
Check what the shell sees:
echo $PATH type -a htop
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.
i) or append-only (a) attribute.Check for special attributes and remove them if they shouldn't be there:
lsattr file sudo chattr -i file
Check what filesystem the file is on:
findmnt --target file
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; 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).
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
For Ansible, pass the become password: ansible-playbook site.yml -K
Careful: Grant NOPASSWD only for the specific commands needed, not ALL.
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.
sudo echo ... > file or sudo cat ... > file.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
Or run the whole command in a root shell:
sudo sh -c "echo 'vm.swappiness=10' > /etc/sysctl.d/99-custom.conf"
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.
/usr/local by default, which belongs to root.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
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.
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.
Check space and inodes:
df -h df -i
Find what's large, staying on one filesystem:
sudo du -xh / --max-depth=2 2>/dev/null | sort -h | tail -n 20
Find deleted-but-open files and restart the process holding them:
sudo lsof -nP +L1 | head
Shrink the systemd journal and clean package caches:
sudo journalctl --vacuum-size=200M sudo apt clean
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.
nfs-common, cifs-utils, ntfs-3g, exfatprogs).-t type.See what's really on the device:
lsblk -f sudo blkid /dev/sdb1
Install the matching helper (Debian/Ubuntu names):
sudo apt install nfs-common cifs-utils ntfs-3g exfatprogs
Read the kernel's detailed reason:
sudo dmesg | tail -n 20
For a hibernated NTFS disk, shut Windows down fully (or turn off Fast Startup) rather than forcing the mount.
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.
cd'd into it, or a process has files open there (an editor, a backup, a service).Find the processes using it:
sudo lsof +f -- /mnt/data sudo fuser -vm /mnt/data
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.
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.
errors=remount-ro).ro on purpose (a container, snap, ISO, or ProtectSystem= in a systemd service).Look for disk errors first:
sudo dmesg -T | grep -iE 'error|ext4|xfs|i/o' | tail -n 20 findmnt -no OPTIONS /
Check the disk's health:
sudo smartctl -a /dev/sda
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 /
/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.
From the recovery shell, repair the named filesystem (it must not be mounted):
fsck -y /dev/sda1
Reboot, then check the disk's health and back up important data:
reboot sudo smartctl -H /dev/sda
cannot access 'file': Structure needs cleaning
EUCLEAN
What it means: The filesystem found corrupted metadata (common wording on ext4 and XFS).
Unmount it (or boot a rescue system for /) and repair:
sudo umount /dev/sdb1 sudo fsck -f /dev/sdb1 sudo xfs_repair /dev/sdb1
Check the disk itself:
sudo smartctl -a /dev/sdb
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.
Let find handle the files instead of the shell:
find /path -maxdepth 1 -type f -name '*.log' -delete
Or pass them in batches:
find /path -maxdepth 1 -type f -name '*.jpg' -print0 | xargs -0 cp -t /dest/
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).
See the limit and how many a process has open:
ulimit -n ls /proc/<pid>/fd | wc -l
For a systemd service, raise it in an override, then restart:
sudo systemctl edit myapp # add: [Service] LimitNOFILE=65536
If the count keeps climbing, the program leaks handles; raising the limit only delays the error.
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.
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
On RHEL-family systems:
sudo dracut -f --regenerate-all sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Check that /boot has free space:
df -h /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.
/etc/fstab, or a disk that was removed._netdev and nofail.Log in, then find the mount that failed:
journalctl -xb | grep -iE 'mount|fstab' | tail systemctl --failed
Make / writable and fix the fstab line (comment it out, or correct the UUID from blkid):
mount -o remount,rw / blkid nano /etc/fstab
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
systemctl daemon-reload mount -a
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.
At the prompt, find the partition that holds /boot/grub:
ls ls (hd0,gpt2)/
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
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
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.
ssh vs sshd, apache2 vs httpd, mysql vs mariadb).systemctl daemon-reload.systemctl --user) or lives in an unusual folder.Search for the right name:
systemctl list-unit-files | grep -i nginx
After adding or editing a unit file, reload systemd:
sudo systemctl daemon-reload sudo systemctl start myapp
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.
Read the service's own error messages:
systemctl status nginx.service journalctl -xeu nginx.service --no-pager | tail -n 40
Many services can check their config without starting:
sudo nginx -t sudo apachectl configtest sudo sshd -t sudo named-checkconf
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.
#! line or has Windows line endings.Check the path and permissions systemd sees:
systemctl cat myapp ls -l /opt/app/run.sh head -1 /opt/app/run.sh
Make it executable and fix line endings:
sudo chmod +x /opt/app/run.sh sudo sed -i 's/\r$//' /opt/app/run.sh
Use a full path to the interpreter if needed: ExecStart=/usr/bin/python3 /opt/app/app.py
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.
Restart= keeps relaunching it.Find the first real error before the restarts:
journalctl -u myapp -b --no-pager | head -n 60
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 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.
systemctl --user in a session without a user bus (su, sudo, cron).In a container, run the program directly instead of as a service (it should be the container's main process).
In WSL, enable systemd in /etc/wsl.conf, then run wsl --shutdown from Windows:
[boot] systemd=true
For user services over SSH, enable lingering and use a proper login session:
sudo loginctl enable-linger $USER
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.
/etc/systemd/system/ by hand.Reload, then restart the service:
sudo systemctl daemon-reload sudo systemctl restart myapp
Tip: sudo systemctl edit myapp creates an override file and reloads for you.
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.
Confirm and see what was killed:
sudo dmesg -T | grep -iE 'killed process|oom' journalctl -k | grep -i oom
See current memory use per process:
free -h ps aux --sort=-%mem | head
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: Cannot allocate memory
ENOMEM: Cannot allocate memory
What it means: The kernel couldn't hand out the memory a program asked for.
Check memory and overcommit settings:
free -h sysctl vm.overcommit_memory vm.overcommit_ratio
Find the biggest memory users:
ps aux --sort=-%mem | head
(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.
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
Or set MAILTO="" at the top of the crontab to drop mail entirely (you'll lose error output).
"/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.
/etc/crontab has one).Check each schedule with the Cron Visualizer, then edit again:
crontab -e
The number after the file name (:3:) is the line to look at.
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.
Best: make the repo owned by the user who uses it:
sudo chown -R $USER: /srv/app
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.
! [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.
Bring their work in, then push:
git pull --rebase origin main git push
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.
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.
Keep your changes aside, pull, then put them back:
git stash git pull git stash pop
If you don't want your local edits (they will be lost):
git restore config.php
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.
.git folder was deleted or not copied.Check where you are and go to the repo's folder:
pwd ls -a cd /path/to/repo
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.
Allow local scripts and signed downloaded ones, for your user only:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
Check the policy at every level:
Get-ExecutionPolicy -List
For a script you trust that was downloaded, remove the internet mark:
Unblock-File .\setup.ps1
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 '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.
PATH.Get-ADUser needs RSAT)..\ in front.Run a script from the current folder:
.\script.ps1
Check where Windows finds it and what PATH contains:
Get-Command kubectl $env:Path -split ';'
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.
What it means: The computer's secret password with Active Directory no longer matches, so domain logins fail.
Log in with a local admin account, then repair the secure channel (prompts for domain admin credentials):
Test-ComputerSecureChannel -Repair -Credential (Get-Credential)
Or reset the machine password:
Reset-ComputerMachinePassword -Credential (Get-Credential)
If that fails, remove the PC from the domain and join it again.
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.
Open PowerShell or cmd with Run as administrator and try again.
Check the file's permissions:
icacls "C:\Program Files\App\config.json"
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.
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
Test reaching a DC:
nltest /dsgetdc:corp.example.com Test-NetConnection dc01.corp.example.com -Port 389
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.
On the target (as administrator), enable remoting:
Enable-PSRemoting -Force
From your machine, test the port and the service:
Test-NetConnection srv01 -Port 5985 Test-WSMan srv01
For non-domain machines, add the target to TrustedHosts:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'srv01' -Concatenate
CrashLoopBackOff
Back-off restarting failed container
What it means: The container keeps starting and crashing, so Kubernetes waits longer and longer between restarts.
Read the logs of the crashed attempt, not just the current one:
kubectl logs <pod> --previous
See the exit code, reason and events:
kubectl describe pod <pod>
ImagePullBackOff
ErrImagePull
Failed to pull image "myapp:latest": rpc error: code = NotFound
What it means: The node can't download the container image.
imagePullSecrets.The events show the exact pull error:
kubectl describe pod <pod> | tail -n 20
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 - 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.
~/.kube/config is missing (common right after kubeadm, or when running as a different user).KUBECONFIG points to a file that doesn't exist.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
For k3s:
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
Check the active context:
kubectl config current-context
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.
Read the scheduler's reason:
kubectl describe pod <pod> | grep -A5 Events
Compare requests with what's free on the nodes:
kubectl describe nodes | grep -A6 'Allocated resources'
On a single-node test cluster, allow pods on the control plane:
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
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.
See what's missing, then check it exists in the same namespace:
kubectl describe pod <pod> kubectl get secret,configmap -n <namespace>
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.
'app'@'%' vs 'app'@'localhost').For socket-authenticated root, log in through sudo:
sudo mysql
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';
List which user and host combinations exist:
SELECT user, host, plugin FROM mysql.user;
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.
Check and start the service, then read why it stopped:
sudo systemctl status mysql mariadb sudo journalctl -u mysql -u mariadb -n 50
Or connect over TCP instead of the socket:
mysql -h 127.0.0.1 -u app -p
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.
Connect over TCP, which normally uses password authentication:
psql -h 127.0.0.1 -U app appdb
Or switch to the postgres OS user to manage roles:
sudo -u postgres psql ALTER USER app WITH PASSWORD 'strong-password';
If you change pg_hba.conf, reload PostgreSQL:
sudo systemctl reload postgresql
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.
listen_addresses), and you connect from another machine.Check the service and where it listens:
sudo systemctl status postgresql sudo ss -tlnp | grep 5432
To accept remote connections, set listen_addresses = '*' in postgresql.conf, add a host line in pg_hba.conf, then restart.
ERROR 1040 (HY000): Too many connections
SQLSTATE[HY000] [1040] Too many connections
What it means: MySQL reached max_connections, so new clients are refused.
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';"
Raise the limit for now if the server has memory to spare, and fix the app's connection pool:
SET GLOBAL max_connections = 300;
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.
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, 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.
dir folder.vm.overcommit_memory is 0).Check the reason Redis reports and free space:
redis-cli INFO persistence | grep -i rdb_last_bgsave df -h
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.
No errors match that filter.
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.