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 base

Fix

#!/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".