nautechsystems/nautilus_trader · error

Lighter query_order requires credentials

Error message

Lighter query_order requires credentials

What it means

query_order performs an authenticated HTTP query against the Lighter API to resolve an order, requiring the credential for signing/authenticating the request. A None credential produces this error. Unlike pure cache lookups, order query goes to the exchange and therefore needs credentials.

Source

Thrown at crates/adapters/lighter/src/execution.rs:4551

            Some(state) => {
                log::debug!("Lighter query_account replaying cached AccountState");
                self.emitter.send_account_state(state);
            }
            None => {
                log::warn!(
                    "Lighter query_account: no AccountState cached yet \
                     (account_all_assets stream has not pushed since connect)",
                );
            }
        }
        Ok(())
    }

    fn query_order(&self, cmd: QueryOrder) -> anyhow::Result<()> {
        let credential = self
            .credential
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("Lighter query_order requires credentials"))?
            .clone();
        let registry = Arc::clone(&self.registry);
        let http_client = self.http_client.clone();
        let emitter = self.emitter.clone();
        let core_account_id = self.core.account_id;
        let dispatch = self.dispatch.clone();
        let clock = self.clock;

        self.spawn_task("query_order", async move {
            let report = lookup_order_status_report(
                &http_client,
                &registry,
                &credential,
                core_account_id,
                Some(cmd.instrument_id),
                Some(&cmd.client_order_id),
                cmd.venue_order_id.as_ref(),
                &dispatch,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Configure credentials on the client before calling query_order
  2. Use the cache-only lookup (order state already known) instead of an exchange query when credentials are unavailable
  3. Verify the credential is loaded (log its presence, never its value) at startup
Defensive patterns

Strategy: validation

Validate before calling

if client.credential().is_none() {
    // fall back to cache-only order state instead of exchange query
    return cache.lookup_order(&cmd.client_order_id);
}

Type guard

fn has_credential(c: &LighterExecutionClient) -> bool {
    c.credential().is_some()
}

Try / catch

match client.query_order(cmd) {
    Err(e) if e.to_string().contains("requires credentials") => {
        // use cached order state or configure credentials
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling query_order on a credential-less Lighter execution client to resolve order status/exchange order id from the exchange.

Common situations: Adapter started without API keys but strategy code calls query_order for reconciliation; keys missing in CI/staging environments; config parsing silently dropping the credential.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ac3c27f29f89e483. Report an issue: GitHub.