Redis error EXECABORT
EXECABORT Transaction discarded because of previous errors.
A command you queued after MULTI was refused straight away (a typo, wrong arguments, no permission, no memory), so at EXEC Redis threw the whole transaction away and ran none of it. The real cause is the error that came before EXEC.
EXECABORT Transaction discarded because of previous errors.
Tested on Redis 8.10.2 and Valkey 8.1.10 · Updated 9 October 2026
What it means
MULTI starts a transaction. The commands after it don’t run yet: Redis checks each one, replies
QUEUED, and keeps it. EXEC then runs them all in one go, with nothing from other clients in
between.
If a command fails that check (an unknown command, the wrong number of arguments, a command your
user may not run, a write the server can’t accept right now), Redis replies with that error at once
and marks the transaction. At EXEC it replies EXECABORT and runs none of the commands, not
even the ones that queued fine. So EXECABORT itself tells you little: the cause is the error
printed earlier, right after the bad command.
Errors that only show up while EXEC runs are different, and catch people out:
- Run-time errors don’t abort.
INCRon a value that isn’t a number, or a list command on a string (WRONGTYPE), queue without complaint. AtEXEC, that one command fails, its error takes its place in the reply, and every other command in the transaction still runs. Redis has no rollback. WATCHdoesn’t produce an error. If a key you watched changed beforeEXEC,EXECreplies with a null ((nil)in redis-cli) and runs nothing. Your code is meant to retry.
Common causes
- A typo or wrong arguments in a queued command:
INCRwith no key,INCRBYwith an extra argument, a misspelt command name. - A command the user may not run, or a key it may not use: the queued command gets NOPERM.
- The server is out of memory (
maxmemoryreached with thenoevictionpolicy): a queued write gets OOM. - Writing to a read-only replica: a queued write gets READONLY.
- On Valkey, a nested
MULTIor aWATCHinside the transaction. Valkey 8 refuses both withERR Command not allowed inside a transactionand aborts the transaction. Redis 8 refuses them too (ERR MULTI calls can not be nested,ERR WATCH inside MULTI is not allowed), but still runs the rest atEXEC.
On a cluster, a transaction whose keys are in different slots fails at EXEC with
CROSSSLOT instead.
How to fix it
Find the first error
In redis-cli the cause is the (error) line between MULTI and EXEC. Client libraries usually
send the whole transaction at once and show only the final error, but keep the earlier one:
- ioredis rejects with
ReplyError: EXECABORT Transaction discarded because of previous errors.and puts the queuing errors in the error’spreviousErrorsarray. - redis-py raises the first queuing error itself rather than
ExecAbortError(from its source).
Fix that command, then run the whole transaction again: nothing from the first attempt was applied.
Check every reply after EXEC
Because run-time errors don’t abort, a successful EXEC can still contain failures. Check each
element of its reply. If some commands must not run unless others succeed, validate first, or move
the logic into a Lua script or function, where you can check values before writing.
Retry when WATCH fires
The usual pattern for check-and-set:
WATCH balance:1
GET balance:1
MULTI
SET balance:1 <new value>
EXEC
If EXEC replies (nil), someone changed balance:1 after your WATCH: read it again and retry.
redis-py raises WatchError for this (Watched variable changed.).
Don’t nest transactions
Send WATCH before MULTI, and finish a transaction with EXEC or DISCARD before starting the
next. The two servers treat a mistake here differently, so code that works on Redis can hit
EXECABORT on Valkey.
Reproduce it
Redis 8.10.2, redis-cli 8.10.2, database 15:
MULTI
OK
SET seo:auth:t1 a
QUEUED
INCR
(error) ERR wrong number of arguments for 'incr' command
EXEC
(error) EXECABORT Transaction discarded because of previous errors.
GET seo:auth:t1
(nil)
The SET had queued, but it never ran. An INCRBY with an extra argument and a misspelt SETT
gave ERR wrong number of arguments for 'incrby' command and
ERR unknown command 'SETT', with args beginning with: 'seo:auth:t1' 'b', then the same
EXECABORT. Run-time errors, by contrast:
MULTI
OK
SET seo:auth:t2 a
QUEUED
INCR seo:auth:t2
QUEUED
LPUSH seo:auth:t2 x
QUEUED
SET seo:auth:t3 b
QUEUED
EXEC
1) OK
2) (error) ERR value is not an integer or out of range
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
4) OK
MGET seo:auth:t2 seo:auth:t3
1) "a"
2) "b"
WATCH: one session ran WATCH seo:auth:w, a second client then ran SET seo:auth:w 20, and the
first session went on:
MULTI
OK
SET seo:auth:w 11
QUEUED
EXEC
(nil)
GET seo:auth:w
"20"
Valkey 8.1.10 gave the same replies, except for a nested MULTI and a WATCH inside the
transaction. After MULTI and a queued SET, Redis 8.10.2 replied:
(error) ERR MULTI calls can not be nested
(error) ERR WATCH inside MULTI is not allowed
1) OK
and Valkey 8.1.10:
(error) ERR Command not allowed inside a transaction
(error) ERR Command not allowed inside a transaction
(error) EXECABORT Transaction discarded because of previous errors.
From Node.js, ioredis 5.11.1 with a transaction holding a SET and an INCR with no key, on both
servers:
ReplyError: EXECABORT Transaction discarded because of previous errors.
previousErrors: [ "ERR wrong number of arguments for 'incr' command" ]
On temporary Redis 8.10.2 servers, a queued write was refused in three other ways, each followed by
EXECABORT at EXEC: by a user limited to other keys
(NOPERM No permissions to access a key), on a server started with --maxmemory 1mb
(OOM command not allowed when used memory > 'maxmemory'.), and on a replica
(READONLY You can't write against a read only replica.).
In Inlet
When the server refuses a command, Inlet shows the message after the EXECABORT code and links to
this page. Edits you make in the key grid don’t need WATCH: each change is checked and applied
atomically by a Lua script that first compares the value with what Inlet loaded, so a value someone
changed in the meantime isn’t overwritten.
Related
- WRONGTYPE Operation against a key holding the wrong kind of value
- NOPERM User reader has no permissions to run the 'set' command
- OOM command not allowed when used memory > 'maxmemory'
- READONLY You can't write against a read only replica
- CROSSSLOT Keys in request don't hash to the same slot
- Redis connection string: redis:// and rediss:// URLs explained