nautechsystems/nautilus_trader · error

Order {client_order_id} is already claimed by execution clie

Error message

Order {client_order_id} is already claimed by execution client {conflicting_client_id} and cannot be claimed by {client_id}

What it means

During Postgres cache setup, index_order_clients (crates/infrastructure/src/sql/queries.rs:1345) claims persisted order_event rows for an execution client, backing the external_order_claims feature on strategies. Before updating, it selects any order_event row for the client_order_id already tagged with a different non-NULL client_id; if one exists it bails, because two execution clients must never own the same order.

Source

Thrown at crates/infrastructure/src/sql/queries.rs:1369

        for (client_order_id, client_id) in claims {
            let conflicting_client_id = sqlx::query_scalar::<_, String>(
                r#"
                SELECT client_id
                FROM "order_event"
                WHERE client_order_id = $1
                  AND client_id IS NOT NULL
                  AND client_id <> $2
                LIMIT 1
            "#,
            )
            .bind(client_order_id.to_string())
            .bind(client_id.to_string())
            .fetch_optional(&mut *transaction)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to validate order client origin: {e}"))?;

            if let Some(conflicting_client_id) = conflicting_client_id {
                anyhow::bail!(
                    "Order {client_order_id} is already claimed by execution client \
                     {conflicting_client_id} and cannot be claimed by {client_id}"
                );
            }

            sqlx::query(
                r#"
                INSERT INTO "client" (id)
                VALUES ($1)
                ON CONFLICT (id) DO NOTHING
            "#,
            )
            .bind(client_id.to_string())
            .execute(&mut *transaction)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to persist execution client {client_id}: {e}"))?;

            let result = sqlx::query(

View on GitHub (pinned to d1527c24af)

Solutions

  1. Configure external_order_claims with the same ClientId as the execution client that originally submitted those orders.
  2. Inspect existing ownership: SELECT DISTINCT client_id FROM order_event WHERE client_order_id = '...'; and reconcile the config to it.
  3. If re-assignment is genuinely intended, repair the persisted client_id on those order_event rows deliberately (backup first) or start with a clean database.
  4. Ensure exactly one node/strategy claims any given client_order_id.
Defensive patterns

Strategy: validation

Validate before calling

-- Run before starting the node with external_order_claims
SELECT client_order_id, DISTINCT_ON (client_order_id) client_id
FROM order_event
WHERE client_order_id = ANY($1)  -- your claimed order ids
  AND client_id IS NOT NULL
ORDER BY client_order_id, created_at DESC;
-- If any returned client_id differs from your configured ClientId, fix the config first.

Try / catch

if let Err(e) = node_builder.build().await {
    let msg = e.to_string();
    if msg.contains("already claimed by execution client") {
        log::error!("external order claim conflicts with persisted ownership: {msg}");
        // reconcile claim client_id with the persisted client_id before restarting
    }
}

Prevention

When it happens

Trigger: Node startup (or an explicit index_order_clients call) with external order claims where a claim (ClientOrderId, ClientId) hits order_event rows already attributed to another client_id: configuring claims under a different execution client than the one that submitted the orders, or two strategies/configs claiming the same client_order_id through different clients.

Common situations: Changing the execution client ID configured for external order claims between runs without re-attributing database rows; copying a node configuration to another machine with a different client_id; both a venue client and a different client name claiming the same orders; renaming client IDs in config after orders were persisted.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@d1527c24af (2026-08-21). Data as JSON: /api/errors/8d037683c9699448. Report an issue: GitHub.