Skip to content

/errors/bash/value-too-great-for-base

bash: value too great for base (error token is ...)

verified onenvironmentlocal · linux 6.18.44-fc-v153 x64 · GNU bash 5.2.21updated
tool
Bash
exit code
1
versions
bash 4.x, bash 5.x
os
linux, macos, windows

value too great for base (error token is "08") means the arithmetic expression contains a number that is not valid in the base bash chose for it. The usual trigger is a leading zero: bash treats 08 and 09 as octal numbers, and 8 and 9 are not octal digits. Prefix the value with 10# to force decimal, for example $((10#$month + 1)).

Reproduce the error

bash
month=08
echo $((month + 1))

Output · exit 1

bash: line 2: 08: value too great for base (error token is "08")

The error token is the exact text bash could not read. With x=3abc the token is 3abc: text that starts with a digit is also parsed as a number first. Text that starts with a letter is treated as a variable name instead, and an unset name evaluates to 0, which is why x=abc gives 1 for $((x + 1)) instead of an error.

How bash picks the base

FormBaseExampleValue
12310$((123))123
01238 (octal)$((0123))83
0x1f16$((0x1f))31
base#numberthe base from 2 to 64$((2#101))5

Only the leading zero is a trap. Any value that comes from date, a log file, a CSV column or a zero-padded loop such as seq -w carries it.

Fix it

Force decimal with 10#:

bash
month=08
echo $((10#$month + 1))

Output

9

Or remove the padding before using the value. Parameter expansion with ${var#0} removes one leading zero, which is enough for two-digit values such as months, days and hours (10# is the safer choice for longer padding):

bash
hour=09
hour=${hour#0}
echo $((hour + 1))

Output

10

Confirm the fix by printing the result: bash returns a number and exit status 0. If the value can be empty, give it a default, ${hour:-0}, because an empty value inside 10# is another error (10#: invalid integer constant).

Validate input from users and files

When the number is not under your control, check it before the calculation:

bash
if [[ $count =~ ^[0-9]+$ ]]; then
  echo $((10#$count * 2))
else
  echo "not a number: $count" >&2
fi

This also stops values with signs, spaces and text from reaching the arithmetic parser. Related comparison errors in [ ] look different: integer expression expected comes from test, not from $(( )).

Platform notes

The octal rule is the same in bash on Linux, macOS and Git Bash. date +%m and date +%d return zero-padded values everywhere, so the error is common in scripts that compute dates.

FAQ

Why does 07 work but 08 fail?

Bash follows the C convention: a leading 0 means octal. 07 is a valid octal number (7), but 08 and 09 contain digits that do not exist in base 8, so bash reports value too great for base.

Does let, (( )) and array indexing have the same problem?

Yes. Every arithmetic context in bash uses the same parser: $(( )), (( )), let and the index of an indexed array all read a leading zero as octal.

How do I read a hexadecimal value instead?

Prefix it with 0x, for example $((0x1f)), or name the base explicitly, for example $((16#1f)). The base can be 2 to 64.

Sources