ABORTED
gRPCERRORNotableConcurrencyHIGH confidence

The operation was aborted

What this means

Indicates the operation was aborted, typically due to a concurrency issue like a transaction abort or a check-and-set failure. This suggests a retry might succeed.

Why it happens
  1. 1A read-modify-write operation failed because the data was modified by another transaction after it was read.
  2. 2A concurrency control mechanism, like optimistic locking, detected a conflict.
  3. 3The server aborted the operation to resolve a deadlock.
How to reproduce

Two clients try to update the same database record at the same time, causing a transaction to be aborted.

trigger — this will error
trigger — this will error
// This usually happens in a read-modify-write sequence.
// 1. Client A reads resource version 5.
// 2. Client B reads resource version 5, modifies it, and writes version 6.
// 3. Client A modifies its copy and tries to write version 6, but the server rejects it.
try {
  await client.updateUser(updateRequestWithOldVersion);
} catch (e) {
  // e.code will be ABORTED
}

expected output

StatusCode.ABORTED: The operation was aborted

Fix 1

Retry the Full Read-Modify-Write Transaction

WHEN When an optimistic concurrency conflict occurs.

Retry the Full Read-Modify-Write Transaction
// Retry the entire transaction
for (let i = 0; i < 3; i++) {
  try {
    const current = await client.getResource(id);
    const updated = modify(current);
    await client.updateResource(updated);
    return; // Success
  } catch (e) {
    if (e.code !== grpc.status.ABORTED) throw e;
  }
}

Why this works

By re-reading the latest version of the data before attempting the write again, the client can resolve the conflict.

Fix 2

Use Pessimistic Locking

WHEN When conflicts are very frequent and retries are costly.

Use Pessimistic Locking
// This requires server-side support for locking.
await client.lockResource({ id });
try {
  const resource = await client.getResource({ id });
  await client.updateResource(modify(resource));
} finally {
  await client.unlockResource({ id });
}

Why this works

Pessimistic locking prevents other clients from accessing a resource while it is being modified, avoiding conflicts altogether.

What not to do

Only retry the write portion of the operation

The client's modification was based on stale data. It must re-read the latest data before trying to apply its changes again.

Sources

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All gRPC errors