Bash error: "value too great for base"
Fix "value too great for base" when Bash interprets a number with leading zeros as octal. Use 10# to force base-10 arithmetic.
Error String
bash: value too great for base
Tldr
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.
Cause
In arithmetic context, a number starting with `0` is parsed as octal (base 8). A number starting with `0x` is hexadecimal. If a variable like `08` or `09` comes from a date, version, or user input, arithmetic evaluation fails because 8 and 9 are not valid octal digits.
Repro
#!/usr/bin/env bash
month=08
day=09
echo $(( month + day )) # value too great for baseFix
#!/usr/bin/env bash
month=08
day=09
echo $(( 10#month + 10#day )) # 17
# Or strip leading zeros first:
month=${month#0}
day=${day#0}
echo $(( month + day ))Explanation
The `10#` prefix forces Bash to interpret the following value as base-10, ignoring any leading zeros. This is essential when handling dates, timestamps, or zero-padded identifiers.
Faq
Q
Does this affect [[ ]] numeric comparisons?
A
No — [[ ]] does not do arithmetic; it does string comparison unless you use -eq/-gt. Use (( )) for arithmetic comparisons.
Q
What about numbers with 0x prefix?
A
0x is valid hexadecimal in arithmetic context. If you want decimal, strip the prefix or use 10#.
Q
Why do only 08 and 09 fail?
A
Octal digits run 0-7, so 8 and 9 are invalid; `01` through `07` parse as octal and silently give the same value as decimal.
Q
Does 10# work on negative numbers?
A
Yes — write `-$(( 10#$n ))` or keep the sign outside the base prefix, as `10#-5` is invalid.
Deep Dive
Heading
Leading zeros mean octal
Body
Bash arithmetic treats a number with a leading zero as octal, so `08` and `09` are invalid digits and produce this error. Zero-padded values from dates are the classic source: `$(date +%m)` gives `08` in August, and `$(( $(date +%m) + 1 ))` fails for exactly two months a year. Force base ten with `$(( 10#$month ))`, which works for unpadded values too, or strip padding with `${month#0}` — remembering that leaves an empty string for `00`.
Heading
Explicit base notation
Body
The `base#value` syntax accepts bases 2 through 64: `2#1010` is 10, `16#ff` is 255, and `10#$n` is the safe idiom for user input. Digits above 9 use letters, so `16#g` fails for a different reason but with the same style of message. When you only need to compare or print padded numbers, avoid arithmetic altogether and use `printf "%02d"` on the way out, keeping unpadded integers internally.
Checklist
Wrap date-derived numbers in `10#`.
Do not store zero-padded values in variables used for arithmetic.
Use `printf "%02d"` only for display.
Remember `${n#0}` yields an empty string for "00".