Redis Error Guide: 'EXECABORT Transaction discarded because of previous errors'
Fix EXECABORT errors in Redis MULTI/EXEC: diagnose queued syntax errors, unknown commands, wrong arity, and how it differs from runtime WRONGTYPE.
- #redis
- #troubleshooting
- #errors
- #transactions
Overview
EXECABORT Transaction discarded because of previous errors is returned by EXEC when at least one command queued inside a MULTI/EXEC transaction could not even be queued — because it was syntactically invalid, an unknown command, or had the wrong number of arguments (arity). Redis detects these errors at queue time: when you send such a command after MULTI, it replies with the error immediately and flags the transaction as dirty. When you finally call EXEC, Redis refuses to run any of the queued commands and returns EXECABORT, so the whole transaction is aborted atomically — nothing is applied.
The literal errors, in sequence:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SETX foo bar
(error) ERR unknown command 'SETX', with args beginning with: 'foo', 'bar'
127.0.0.1:6379> INCR counter
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
This differs from a runtime error (e.g. WRONGTYPE): those are not caught at queue time, so EXEC still runs and returns per-command errors in the reply array while other commands succeed. EXECABORT is specifically the “couldn’t queue” case.
Symptoms
EXECreturnsEXECABORTand none of the transaction’s writes took effect.- Just before it, one queued command returned
ERR unknown commandorERR wrong number of arguments. - A pipeline/transaction from application code fails wholesale after a client-library or command-name change.
- Retrying the same transaction fails identically — it is deterministic.
redis-cli EXEC
(error) EXECABORT Transaction discarded because of previous errors.
Common Root Causes
1. Unknown / misspelled command
A typo or a command that does not exist in this Redis version (e.g. a module command when the module is not loaded).
(error) ERR unknown command 'SETX', with args beginning with: ...
2. Wrong arity (too few / too many arguments)
SET with only a key, HSET with an odd number of field/value args, etc.
(error) ERR wrong number of arguments for 'set' command
3. Command not available in the deployment
Using a newer command against an older server, or an ACL that denies the command so it fails to queue.
redis-cli COMMAND INFO getex # empty array => command unknown on this server
redis-cli ACL WHOAMI
redis-cli ACL GETUSER default | grep -A2 commands
4. Client library building a malformed command
A driver that concatenates arguments wrong, or interpolates an empty/nil argument, sends an invalid command that Redis rejects at queue time.
Diagnostic Workflow
Step 1: Reproduce interactively to see the queue-time error
redis-cli
127.0.0.1:6379> MULTI
127.0.0.1:6379> <the failing command exactly as the app sends it>
The error printed here (unknown command or wrong number of arguments) is the real cause; EXECABORT is just the downstream effect.
Step 2: Validate the command exists and its arity
redis-cli COMMAND INFO <cmd> # arity, flags; empty => unknown
redis-cli COMMAND COUNT # sanity: server has commands loaded
redis-cli COMMAND DOCS <cmd> 2>/dev/null | head
COMMAND INFO returns the arity (negative = variadic minimum). Compare against what the app sends.
Step 3: Check ACLs and server version
redis-cli INFO server | grep redis_version
redis-cli ACL WHOAMI
redis-cli ACL GETUSER <user>
A denied command under ACLs also fails to queue and triggers EXECABORT.
Step 4: Capture what the client actually sent
# Briefly, on a low-traffic node
redis-cli MONITOR | grep -iE 'MULTI|EXEC|<suspect-cmd>'
MONITOR shows the exact bytes the driver queued — often revealing an empty or extra argument.
Example Root Cause Analysis
After upgrading a client library, a batch job’s transactions began failing entirely with EXECABORT, and no counters advanced. Reproducing the transaction by hand:
redis-cli
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> HSET cfg:1 enabled
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> INCR cfg:version
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
The new library serialized a config map that happened to contain a key with a nil value, so it emitted HSET cfg:1 enabled with the value missing — wrong arity. Redis rejected it at queue time and aborted the whole transaction (correctly protecting atomicity), so the INCR never ran either.
The fix was in the application: filter out nil values before building the HSET, and add a guard that raises client-side if any transaction command has invalid arity, rather than discovering it only at EXEC. After the fix, COMMAND INFO hset confirmed the expected arity and the transactions applied cleanly.
Prevention Best Practices
- Validate command names and argument counts in application code before queuing them in a
MULTI. - Never interpolate
nil/empty values into command arguments; filter them first. - Pin and test client-library versions; a driver change can alter how commands are serialized.
- Keep server and client feature-compatible — do not send commands newer than the server, or ones blocked by ACLs.
- Distinguish
EXECABORT(queue-time, whole transaction discarded) from runtime errors likeWRONGTYPE(per-command, transaction still executes) when debugging. - See more Redis error guides for related transaction and type issues.
Quick Command Reference
# Reproduce and see the real queue-time error
redis-cli
> MULTI
> <failing command>
# Validate the command and arity
redis-cli COMMAND INFO <cmd>
redis-cli COMMAND COUNT
redis-cli INFO server | grep redis_version
# ACL / permission checks
redis-cli ACL WHOAMI
redis-cli ACL GETUSER <user>
# See exactly what the client sent (use briefly)
redis-cli MONITOR | grep -iE 'MULTI|EXEC'
Conclusion
EXECABORT Transaction discarded because of previous errors means a command inside your MULTI/EXEC could not be queued, so Redis atomically discards the entire transaction at EXEC — nothing is applied. The trigger is always a queue-time error you saw earlier:
- An unknown or misspelled command.
- Wrong arity (too few/too many arguments).
- A command unavailable in this server version or blocked by ACLs.
- A client library building a malformed command (empty/extra argument).
Reproduce the transaction interactively to surface the real error, validate the command with COMMAND INFO, and fix the argument construction in the application. Remember: EXECABORT is the “couldn’t queue” case — runtime errors like WRONGTYPE behave differently and still execute the rest of the transaction.
Download the Free 500-Prompt DevOps AI Toolkit
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.