Bash Error Guide: 'printf: invalid number' — Fix Numeric Format Args
Fix Bash 'printf: invalid number': strip whitespace and non-digits before %d, validate input, and use %s or bc for decimals printf can't format.
- #bash
- #automation
- #troubleshooting
- #errors
Stuck on this Bash & Python Automation error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
Bash’s printf prints invalid number when a value handed to a numeric conversion (%d, %i, %x, %o) isn’t a valid integer:
./stats.sh: line 14: printf: 1,024: invalid number
%d expects a plain integer. Anything with a comma, a decimal point, trailing units, leading/trailing whitespace, or embedded letters makes printf warn invalid number, substitute 0, and continue with a non-zero-ish exit. It’s a data-validation error surfacing at format time — the number you fed in wasn’t the number printf can parse.
Symptoms
printf '%d'warnsinvalid numberand prints0instead of your value.- The value looks numeric to a human (
1,024,3.5,42%,12) but isn’t a bare integer. - Output shows
0where a count or size should be, corrupting reports and comparisons downstream. - It appears when formatting the output of
du,df,awk, or an API that returns numbers with separators or units.
Common Root Causes
- Thousands separators —
1,024or1 024;printf %donly accepts unseparated digits. - A decimal/float —
3.5;%dis integer-only (use%.0for%s). - Trailing units or symbols —
42%,12ms,2G. - Leading/trailing whitespace or a stray
\rfrom a CRLF file or command output. - Empty value — an unset variable expands to nothing, and
%dtreats “no argument” or empty as invalid/zero. - Locale-formatted numbers where the decimal or grouping character differs.
Diagnostic Workflow
Reveal exactly what’s in the value, including hidden characters:
val="1,024"
printf '%q\n' "$val" # shows quotes/commas/whitespace/\r escaped
Test whether it’s a clean integer before formatting:
[[ "$val" =~ ^-?[0-9]+$ ]] && echo "int" || echo "not an int: [$val]"
Trace the failing call:
bash -x ./stats.sh 2>&1 | grep -i 'invalid number\|printf'
Example Root Cause Analysis
A capacity report formatted disk usage:
USED=$(df -h /data | awk 'NR==2 {print $3}') # e.g. "2.3G"
printf 'Used: %d GB\n' "$USED"
It emitted:
report.sh: line 2: printf: 2.3G: invalid number
Used: 0 GB
df -h returns human-readable values (2.3G) with a unit suffix and a decimal — neither valid for %d. Two correct fixes depending on intent. To print the raw string, use %s:
USED=$(df -h /data | awk 'NR==2 {print $3}')
printf 'Used: %s\n' "$USED" # "Used: 2.3G"
To do integer math, pull machine-readable bytes and let printf/numfmt format:
BYTES=$(df -B1 /data | awk 'NR==2 {print $3}') # plain integer bytes
printf 'Used: %d bytes (%s)\n' "$BYTES" "$(numfmt --to=iec "$BYTES")"
Now the value passed to %d is a bare integer, and human formatting is handled separately.
Prevention Best Practices
- Validate before formatting — gate
%dbehind[[ "$v" =~ ^-?[0-9]+$ ]]and handle non-integers explicitly. - Use
%sfor display when the value carries units or separators you want to keep verbatim. - Fetch machine-readable numbers —
df -B1,--bytes, or API fields without separators, then format withnumfmt/printf. - Strip whitespace and
\r—v=${v//[$'\t\r ']/}or rundos2unixon inputs from Windows. - Do decimal math with
awk/bc, notprintf %d, which truncates and can’t parse floats. - Default empty values —
${v:-0}so an unset variable doesn’t silently become an invalid number.
Quick Command Reference
[[ "$v" =~ ^-?[0-9]+$ ]] || { echo "not int: $v"; exit 1; } # validate
printf '%s\n' "$v" # display value with units as-is
v=${v//,/} # strip thousands separators
v=${v//[$'\t\r ']/} # strip whitespace and CR
numfmt --to=iec "$bytes" # format an integer to 2.3G safely
printf '%d\n' "$(( v ))" # force arithmetic context (ints only)
Related Guides
- Bash Error Guide: ‘integer expression expected’ — the
[ ]cousin, when a numeric test gets a non-number. - Bash Error Guide: ‘unary operator expected’ — another test/format failure from unvalidated input.
- Bash & Python Error Guide: ‘command not found’ — when the tool producing your numbers isn’t even on PATH.
Conclusion
printf: invalid number means a value bound to %d/%x wasn’t a bare integer — it had a comma, a decimal, a unit, whitespace, or a stray \r. Validate with a regex before formatting, use %s when you want to keep units, and pull machine-readable numbers (df -B1, numfmt) for math. Guard your format arguments and reports stop silently printing 0 where real numbers belong.
Fixed it? Get 500 Bash & Python Automation & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.