Sui.

Post

Share your knowledge.

Bounty+15

Xavier.eth.
Jun 27, 2025
Expert Q&A

Sui Transaction Failing: Objects Reserved for Another Transaction

I'm encountering a persistent JsonRpcError when trying to execute transactions on Sui. The error indicates that objects are reserved for another transaction, even though I've implemented sequential transaction processing with delays.

JsonRpcError: Failed to sign transaction by a quorum of validators because one or more of its objects is reserved for another transaction. Other transactions locking these objects:
- AV7coSQHWg5vN3S47xada6UiZGW54xxUNhRv1QUPqWK (stake 33.83)
    - 0x1c20f15cbe780ee7586a2df90c1ab70861ca77a15970bea8702a8cf97bd3eed9
    - 0x1c20f15cbe780ee7586a2df90c1ab70861ca77a15970bea8702a8cf97bd3eed9
    - 0x1c20f15cbe780ee7586a2df90c1ab70861ca77a15970bea8702a8cf97bd3eed9

I've tried:

  • Sequential transaction execution (waiting for previous transaction to complete)
  • Added 3-second delays between transactions

And still getting the same error consistently.

Using Sui RPC for transaction submission. The same object ID appears multiple times in the lock list. Error occurs even with careful transaction sequencing.

  1. What causes objects to be "reserved" for other transactions?
  2. How can I properly check if an object is available before using it in a transaction?
  3. Are there best practices for handling object locks in Sui?
  4. Could this be related to transaction finality timing?

Has anyone encountered this issue before? Any insights on proper object management in Sui transactions would be greatly appreciated!

  • Sui
  • Transaction Processing
  • Move
2
5
Share
Comments
.

Answers

5
0xduckmove.
Jun 30 2025, 07:04

Hey, you are trying to do a transaction too fast and the objects got locked.

Try to send one transaction with the same objects at a time, if you send two transactions some validators might accept the first some might accept the second and you objects will be locked because each transactions needs 66.7% of validators and you might be getting only 50%.

=> just wait for the epoch reset, it's soon 🫡

Check more: https://forums.sui.io/t/beginner-tutorial-error-when-deploying-simple-sui-package/44842

3
Comments
.
Owen.
Owen486
Jun 30 2025, 11:03

Sui uses optimistic concurrency control, meaning objects are locked when used in a transaction until that transaction is finalized or expires.

Even if you wait 3 seconds between transactions, if the previous one hasn't been finalized, the object remains locked. This means that transaction is still pending and holding exclusive access to the object.


How to Check If an Object Is Available

Use the Sui RPC method:

sui_getObject

Check response for "status": "Locked" or "owner": "locked".

Example request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "sui_getObject",
  "params": ["0x...object_id..."]
}

If locked, just wait more and retry later.

3
Comments
.
MiniBob.
Jun 30 2025, 11:50

The error means the objects your transaction uses are still locked by previous transactions not yet finalized. Even with delays, objects remain reserved until those transactions complete on-chain.

To fix:

  1. Always confirm prior transactions involving the objects have fully finalized before using them again.
  2. Check object status via Sui RPC to ensure they’re unlocked.
  3. Avoid sending parallel or rapid transactions on the same objects.
  4. Implement retries with backoff and finality checks instead of fixed delays.

This locking prevents conflicting updates and is normal in Sui’s object model. Proper sequencing and finality confirmation are key to avoiding JsonRpcError.

3
Comments
.
harry phan.
Jun 30 2025, 15:00

This error happens if you try and run two transactions simultaneously (e.g. start one before the previous one finishes). If you retry running the publish transaction, without running another transaction before or at the same time, it should succeed. You may also need to acquire more gas from the faucet (or wait a day – for the epoch to roll over – for the objects to get unlocked)

When you run a transaction that involves objects that your address owns (like the gas objects) validators reserve the latest version of the object to be used by the transaction it is signing. If you try and run two transactions simultaneously and they refer to the same object, then they will compete with each other for signatures from validators. In the happy case, one of the transactions wins, and runs, and the other transaction fails to get enough signatures. In the unhappy case, both transactions can fail to get enough signatures (if both got more than a third of the validator’s signatures, then neither can get over two thirds, which is the threshold), this is called equivocation, and from that point the objects that were inputs to both transactions can’t be used for any other transactions.

At the end of the epoch (they are roughly a day long – you can check progress to the next epoch change on https://suiexplorer.com), all locks are released, so you can use the objects again, but if you haven’t had an epoch change since you last tried, you will need to acquire more gas.

3
Comments
.
24p30p.
Jul 9 2025, 04:14

On the Sui network, when a transaction attempts to access an object that’s already involved in another in-progress transaction, the network returns a reservation error. This is a direct consequence of Sui’s object-centric execution model. Any transaction that mutates or consumes an object must acquire an exclusive lock on it. Once such a transaction is submitted, the object remains reserved until the transaction reaches finality. That reservation prevents other transactions from interacting with the same object prematurely, thereby ensuring atomicity and avoiding race conditions. However, if finality is delayed due to network latency, validator lag, or unexpected execution behavior, the object can remain locked longer than anticipated.

To determine whether an object is in a usable state, you can utilize the sui_getObject method through Sui’s JSON-RPC interface or the Sui CLI. Examining the object's owner field or transaction lock metadata can provide clarity on its status. If the object appears to be in use or does not return ownership to the expected address, it is likely still reserved. An even more robust approach involves programmatically polling the network until the object's lock is released—particularly helpful in automated flows or when orchestrating multiple sequential transactions.

Handling these locks effectively demands a few key practices. It's critical to avoid reusing mutable objects across transactions until the previous operations involving them are fully finalized. You should consider using separate or rotating gas coins and object instances wherever possible to reduce contention. Additionally, incorporating retry logic and intelligent polling mechanisms—such as exponential backoff—can minimize transaction failure rates. When transactions are orchestrated in parallel, isolating object usage per process or thread greatly improves reliability.

It’s important to note that this behavior is intimately tied to transaction finality. Even if a transaction is accepted into the mempool and broadcasted, the associated object locks remain in place until the network’s validator quorum confirms the transaction’s final state. Any attempt to reuse that object beforehand, regardless of the use of arbitrary time-based delays, will likely result in a reservation error.

To streamline object lock handling, here’s a Bash utility you can use in your development workflow. It polls the fullnode and waits for the objects to become unlocked before proceeding with a transaction. This ensures that the object is safe to reuse and mitigates premature failure.

Bash Script: wait-for-unlock.sh

#!/bin/bash

# Sui Fullnode RPC endpoint (adjust as needed)
RPC_ENDPOINT="https://fullnode.testnet.sui.io:443"

# Checks if object is locked
is_locked() {
    obj_id=$1
    lock_info=$(curl -s -X POST $RPC_ENDPOINT \
        -H "Content-Type: application/json" \
        -d '{
            "jsonrpc": "2.0",
            "method": "sui_getObject",
            "params": ["'"$obj_id"'"],
            "id": 1
        }')
    
    echo "$lock_info" | grep -q '"owner":{"AddressOwner"' && return 1 || return 0
}

# Waits until each object is no longer locked
wait_for_unlock() {
    for obj_id in "$@"; do
        echo "Checking object $obj_id..."
        while is_locked $obj_id; do
            echo "Object $obj_id is still locked. Retrying in 2s..."
            sleep 2
        done
        echo "Object $obj_id is now unlocked."
    done
}

# Main handler
main() {
    if [ $# -eq 0 ]; then
        echo "Usage: $0 <object_id_1> <object_id_2> ..."
        exit 1
    fi

    wait_for_unlock "$@"
    echo "All objects unlocked. Safe to proceed with transaction."
}

main "$@"

To use the script, simply make it executable and provide the object IDs you want to track. It will poll until those objects are no longer reserved by pending transactions, ensuring your next transaction proceeds smoothly.

chmod +x wait-for-unlock.sh
./wait-for-unlock.sh 0xYOUR_OBJECT_ID

This type of automation is especially effective when integrated into deployment scripts or CI/CD pipelines, providing a layer of resilience in high-throughput or multi-user applications.

0
Comments
.

Do you know the answer?

Please log in and share it.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

400Posts559Answers
Sui.X.Peera.

Earn Your Share of 1000 Sui

Gain Reputation Points & Get Rewards for Helping the Sui Community Grow.

Reward CampaignJuly