Common Bash error messages

Reference for common Bash error messages, with a minimal reproduction, root cause, debugging steps and corrected code for each error.

Find the exact message from your terminal, then follow a focused explanation of its cause, a minimal reproduction and reliable fixes.

  • Bash error: "unbound variable"

    You get "bash: NAME: unbound variable" when set -u (nounset) is enabled and the script reads a variable that was never assigned. Fix it by giving the variable a default with ${NAME:-default} or by assigning it before use.

  • Bash error: "ambiguous redirect"

    Bash redirections accept a single filename. When the variable holding the target is unquoted and contains whitespace, it word-splits into multiple words and Bash refuses with "ambiguous redirect". Quote the variable to fix it.

  • Bash: "No such file or directory" on a file that exists

    When the script is present but Bash still says "No such file or directory", the missing file is usually the interpreter in the shebang, not the script. CRLF line endings on the shebang line are the most common cause.

  • Bash error: "integer expression expected"

    Numeric test operators like -eq, -lt, -gt require both sides to parse as integers. Empty strings or non-numeric values trigger this error. Validate or default the variable before the test.

  • Bash error: "[: too many arguments"

    The `[` command (alias `test`) expects a fixed argument layout. An unquoted variable that holds whitespace word-splits into multiple args and breaks parsing. Quote the variable, or switch to `[[ ]]` which doesn't word-split.

  • Bash syntax error: unexpected `then`

    Bash needs a terminator (semicolon or newline) between the `if` condition and the `then` keyword. Missing it is the #1 cause of this error.

  • Bash error: division by 0

    Arithmetic divisions in `(( ))` or `$(( ))` abort when the divisor is 0. Empty/unset variables count as 0, so check before dividing.

  • Bash error: cannot execute binary file: Exec format error

    The kernel doesn't recognize the file format. The most common causes for a shell script are a missing shebang line, a UTF-8 BOM at the start of the file, or running an architecture-specific binary on the wrong CPU.

  • Bash error: Broken pipe (SIGPIPE)

    A "Broken pipe" warning means the program writing to the pipeline tried to write after the reader closed. It is normal when piping into `head`, `grep -q`, or anything that exits early. To suppress it, use `head -c` carefully, trap SIGPIPE, or accept the harmless exit code.

  • Bash error: Argument list too long

    The kernel limits the total bytes of arguments + environment for a process (typically ~2 MB). A glob that expands to tens of thousands of files exceeds it. Use `find ... -delete`, `find ... -exec ... +`, or `xargs` to batch.

  • Bash error: "parameter null or not set"

    You explicitly guarded a variable with `${VAR:?message}`. The message fires because VAR is unset or empty. Either set the variable, or switch to `${VAR-default}` to allow empty values.

  • Why `set -e` does not exit on failure

    `set -e` is intentionally lenient: it ignores failures inside conditionals (`if`, `&&`, `||`, `!`), inside the test of a loop, and inside pipelines (only the last command's exit status counts unless `pipefail` is set). Add `set -o pipefail` and check command exit codes explicitly when you need strict failure semantics.

  • Bash error: "readonly variable"

    A variable was marked `readonly` (often by `set -o`, a sourced library, or a previous run of the same script in an interactive shell). It cannot be reassigned or unset for the lifetime of the shell. Start a fresh shell or use a different variable name.

  • "Killed" message in Bash

    When a bash process is terminated by SIGKILL, the parent shell prints "Killed" with no other context. The two common causes are the Linux OOM killer (the process used too much memory) and a deliberate `kill -9` from another process or container orchestrator.

  • Bash error: option requires an argument (getopts)

    In `getopts "f:"`, the colon after `f` means "-f takes an argument". Passing `-f` alone triggers this error. Either pass `-f VALUE`, mark the option as flag-only by removing the colon, or use `:` at the start of the option string to opt into silent error handling.

  • Bash error: no such job

    Job control (`%1`, `%+`, `%foo`) only works on jobs started by the current shell. Scripts run with the default settings have job control off; subshells can't see the parent's jobs. Use PIDs and `wait $pid` for portable background-process control.

  • Bash: function "command not found" in a subshell

    Bash functions are local to the shell that defined them. `bash -c` subprocesses, scripts, and other tools that exec a new shell don't inherit them. Export with `export -f my_function`, or source the defining file from the child.

  • Bash error: Text file busy (ETXTBSY)

    The kernel protects running binaries by refusing exec when the file is open for writing. The fix is to finish writing (close the editor or the redirection) before invoking the script, or to write atomically via temp file + `mv`.

  • Bash gotcha: pipeline returns the wrong exit code

    By default `a | b` returns `b`'s exit code, even if `a` failed. Set `set -o pipefail` so the pipeline fails if any stage fails. Combine with `set -e` for fail-fast scripts.

  • Bash error: "cannot execute binary file: Exec format error"

    This means the kernel could not load the file as an executable — either it is a compiled binary built for a different CPU architecture (e.g. an ARM binary on x86_64), or a script with no valid shebang line, or a shell script mistakenly marked and executed as a binary. Check the file type with `file` and re-run through the correct interpreter or architecture.

  • Bash error: "Read-only file system"

    The filesystem backing the path is mounted read-only, either intentionally (mount -o ro, a Docker container with a read-only root, an immutable /nix or squashfs layer) or because the kernel detected corruption and remounted it read-only for safety. Check with `mount | grep <path>` and remount read-write, or write to a writable path instead.

  • Bash error: "fork: retry: Resource temporarily unavailable"

    This means the kernel refused to create a new process (fork) because a limit was hit — most often the per-user process/thread ulimit (`ulimit -u`), the system-wide PID max, or available memory being exhausted. Check `ulimit -u`, `ps -u $USER | wc -l`, and system memory, then raise the limit or reduce concurrent processes.

  • Bash error: "let: division by 0"

    Bash's let and $(( )) arithmetic evaluate expressions using integer math, so any division or modulo by zero — including accidental ones from typos like a stray / where you meant a different operator — aborts with this error. Guard the divisor or fix the expression, and remember `let x++` returns a false exit status when x was 0 before incrementing, which trips set -e.

  • Bash error: "maximum function nesting level exceeded"

    Bash aborts once function calls nest deeper than FUNCNEST (or an internal safety limit if FUNCNEST is unset) to protect against stack exhaustion from infinite recursion. This error almost always means a function is calling itself, directly or through another function, without a base case that stops the recursion.

  • Bash error: "bad array subscript"

    "bad array subscript" means you used an index type the array does not support. Indexed arrays (arr=(...)) take integer keys. Associative arrays (declare -A) take string keys. Mixing the two causes this error.

  • Bash error: "value too great for base"

    Bash treats integer literals with leading zeros as octal. Digits 8 or 9 in those numbers cause "value too great for base". Force decimal with `10#value` inside `(( ))` or arithmetic expansion.

  • Bash error: "syntax error: operand expected"

    Inside `(( ))` or `$(( ))`, every operand must be a number or a variable that expands to a number. Empty strings, non-numeric text, or unquoted spaces cause this error. Default the variable first or validate the input.

  • Bash error: "cannot assign to non-variable"

    This error means the left-hand side of an assignment is not a valid variable name. Common causes: spaces around `=`, assigning to a command substitution like `$(cmd)=value`, or using `export`/`local` with a complex expression.