Bash error: "maximum function nesting level exceeded"

Fix Bash "maximum function nesting level exceeded". Almost always infinite recursion from a function calling itself or a mutual recursion bug.

Error String

bash: maximum function nesting level exceeded

Tldr

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.

Cause

Bash functions do not have tail-call optimization, and each nested call consumes shell stack space. A typo where a function calls its own name instead of an external command of the same name (a common mistake when wrapping a builtin or binary, e.g. defining `ls() { ls --color=auto "$@"; }` without command/\ prefixing) causes unbounded recursion. Bash detects excessive nesting — either the FUNCNEST limit you set, or eventually a stack overflow — and aborts with this message.

Repro

#!/usr/bin/env bash
ls() {
  ls --color=auto "$@"   # calls itself, not the ls binary -> infinite recursion
}
ls
# bash: maximum function nesting level exceeded (100)

Fix

#!/usr/bin/env bash
set -euo pipefail

# Use 'command' to bypass the function and call the real binary
ls() {
  command ls --color=auto "$@"
}
ls

# Or prefix with a backslash to skip alias/function lookup for one call
ls() {
  \ls --color=auto "$@"
}

# For legitimate recursive functions, always include a base case
factorial() {
  local n=$1
  if (( n <= 1 )); then
    echo 1
    return
  fi
  echo $(( n * $(factorial $((n - 1))) ))
}
factorial 5

Explanation

When wrapping a command with a function of the same name, always call through `command <name>` or a backslash-escaped name so the function does not call itself. For genuine recursive algorithms, verify the base case is reachable and consider setting `shopt -s | grep FUNCNEST` or `export FUNCNEST=200` to fail fast during development instead of exhausting the stack.

Faq

Q

What is FUNCNEST and what is its default?

A

FUNCNEST is a Bash shell variable that caps function call nesting depth. It is unset by default (no limit besides the process stack), but scripts can set it (e.g. `FUNCNEST=50`) to catch runaway recursion early with a clear error instead of a hard crash.

Q

Why does wrapping a builtin/command in a same-named function cause this?

A

Inside the function body, a bare call to that name resolves to the function itself (functions are looked up before external commands), so the "wrapper" recurses into itself instead of invoking the real command. Use `command name` or `\name` to call the original.

Q

Is there a real recursion depth limit even without FUNCNEST set?

A

Yes — the underlying process stack is finite, so unbounded recursion eventually crashes even without FUNCNEST configured; setting FUNCNEST just gives you a controlled, catchable failure well before that point.