Redis Error Guide: 'ERR value is not an integer or out of range' — Fix Numeric Command Failures
Fix Redis 'ERR value is not an integer or out of range': non-numeric strings passed to INCR/EXPIRE/SETRANGE, float-vs-int confusion, 64-bit overflow, and out-of-range index arguments.
- #redis
- #database
- #troubleshooting
- #errors
Stuck on this Redis 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
Redis returns this when a command expects an integer argument (or an integer-encoded value) and gets something it cannot parse or that exceeds the signed 64-bit range:
(error) ERR value is not an integer or out of range
You will most often trigger it with the counter and expiry family:
127.0.0.1:6379> SET counter "10x"
OK
127.0.0.1:6379> INCR counter
(error) ERR value is not an integer or out of range
Or by passing a non-integer where a numeric argument belongs:
127.0.0.1:6379> EXPIRE session:42 "60s"
(error) ERR value is not an integer or out of range
127.0.0.1:6379> LPOP queue 2.5
(error) ERR value is not an integer or out of range
Redis stores many values as strings but interprets them numerically for a specific set of commands. INCR, INCRBY, DECR, EXPIRE, PEXPIRE, SETEX, GETRANGE, SETRANGE, LPOP/RPOP count, HINCRBY, and index/count arguments all require a valid base-10 integer that fits in a signed 64-bit value (-9223372036854775808 to 9223372036854775807). Anything else — a decimal, a suffix, leading/trailing whitespace, an empty string, or a number past the 64-bit ceiling — produces this error.
Symptoms
INCR/INCRBY/DECR/HINCRBYfail on a key that “looks like” a number.EXPIRE/SETEX/PEXPIREreject a TTL argument that includes units ("60s") or a float.- The error appears only for certain keys — the ones whose stored string is not a clean integer.
- A counter works for a while, then fails once it crosses
9223372036854775807(64-bit overflow). - Application code that concatenates or formats numbers before writing them to Redis.
Common Root Causes
- Non-numeric string stored, then incremented — a value like
"10x","1,000", or" 10"(whitespace) failsINCR. - Float passed where an integer is required —
INCRneeds an integer; useINCRBYFLOATfor decimals. TTLs and counts must be whole integers. - Units or formatting in the argument —
"60s","5m","3.0"are not integers to Redis. - 64-bit overflow — a counter incremented past
INT64_MAX(or belowINT64_MIN). - Empty or missing value — an unset key is treated as
0byINCR, but an empty-string value (SET k "") is not an integer. - Wrong argument order — passing a member/value where Redis expects a numeric count or index (e.g.
ZADD/LPOPargument mix-ups). - Locale-formatted numbers — thousands separators or comma decimals from client-side formatting.
Diagnostic Workflow
Inspect the actual stored value and its type/encoding:
redis-cli TYPE counter
redis-cli GET counter
redis-cli OBJECT ENCODING counter # 'int' = clean integer; 'embstr'/'raw' = string
redis-cli STRLEN counter
Reveal hidden characters (whitespace, units, non-digits) that break parsing:
redis-cli --no-raw GET counter # shows quoting so " 10" or "10\n" is visible
Reproduce with a known-good value to confirm it is the data, not the command:
redis-cli SET probe 10
redis-cli INCR probe # (integer) 11 -> command is fine
Check for overflow on a long-lived counter:
redis-cli GET big:counter # compare against 9223372036854775807
Confirm you are using the right command for the type of number:
# Integer step -> INCRBY ; fractional step -> INCRBYFLOAT
redis-cli INCRBY price 1
redis-cli INCRBYFLOAT price 1.50
Example Root Cause Analysis
A rate-limiter began throwing ERR value is not an integer or out of range for a subset of users. The counter keys were created by application code that wrote SET rl:{user} "0 " — a trailing space had crept in from a format string. redis-cli --no-raw GET rl:demo revealed "0 " rather than "0".
INCR parses the whole string strictly, so the trailing space made it non-integer, and every increment for those keys failed. The keys created without the stray space incremented fine, which is why only some users were affected.
Fix: corrected the writer to SET rl:{user} 0 (or better, let INCR auto-create the key from unset, which starts at 0), and backfilled the corrupted keys by re-setting them to a clean integer. Increments succeeded immediately, and OBJECT ENCODING reported int again.
Prevention Best Practices
- Never pre-format numbers as strings before storing them for counters — write clean integers, or let
INCRauto-initialize an unset key to0. - Use
INCRBYFLOAT/HINCRBYFLOATfor fractional math andINCR/INCRBY/HINCRBYfor whole numbers — pick the command to match the value. - Pass TTLs as plain integer seconds/milliseconds (
EXPIRE k 60), never with unit suffixes. - Validate and trim numeric inputs in application code before sending them to Redis (no whitespace, separators, or locale formatting).
- For counters that could grow enormous, plan for 64-bit limits — shard or reset periodically before overflow.
- Add integration tests that exercise
INCR/EXPIREpaths with edge-case inputs.
Quick Command Reference
# Inspect the offending value
redis-cli TYPE key
redis-cli --no-raw GET key # exposes whitespace / units / non-digits
redis-cli OBJECT ENCODING key # want 'int'
# Repair a corrupted counter
redis-cli SET key 0 # clean integer
redis-cli INCR key # (integer) 1
# Use the right numeric command
redis-cli INCRBY visits 5 # integer step
redis-cli INCRBYFLOAT price 2.50 # fractional step
redis-cli EXPIRE session:42 60 # TTL in plain integer seconds
# Prove the command works with good data
redis-cli SET probe 100 && redis-cli INCR probe
Conclusion
ERR value is not an integer or out of range is Redis being strict: the numeric commands demand a clean, whole, 64-bit-range integer, and anything with whitespace, units, decimals, or overflow is rejected. Inspect the raw stored value with --no-raw GET, match the command to the number type (INCR vs INCRBYFLOAT), keep application code from formatting numbers before storage, and plan for the 64-bit ceiling on long-lived counters.
Fixed it? Get 500 Redis & 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.