nautechsystems/nautilus_trader · error · anyhow::Error
Transaction broadcast failed: code={}, log={}
Error message
Transaction broadcast failed: code={}, log={} What it means
`broadcast_tx` submits a transaction to the dYdX chain in sync broadcast mode; if the node's tx_response reports a non-zero code, the TX was rejected and the method bails with the chain's code and raw log. This surfaces on-chain rejection reasons (insufficient fees, sequence mismatch, invalid order, etc.).
Source
Thrown at crates/adapters/dydx/src/grpc/client.rs:488
.gas_used;
Ok(gas_used)
}
/// Broadcast a signed transaction.
///
/// # Errors
///
/// Returns an error if broadcasting fails.
pub async fn broadcast_tx(&mut self, tx_bytes: Vec<u8>) -> Result<TxHash, anyhow::Error> {
let req = BroadcastTxRequest {
tx_bytes,
mode: BroadcastMode::Sync as i32,
};
let response = self.tx.broadcast_tx(req).await?.into_inner();
if let Some(tx_response) = response.tx_response {
if tx_response.code != 0 {
anyhow::bail!(
"Transaction broadcast failed: code={}, log={}",
tx_response.code,
tx_response.raw_log
);
}
Ok(tx_response.txhash)
} else {
Err(anyhow::anyhow!(
"Broadcast response does not contain tx_response"
))
}
}
/// Query transaction by hash.
///
/// # Errors
///
/// Returns an error if the query fails.View on GitHub (pinned to 18893faf8b)
Solutions
- Read `code` and `raw_log` in the message — the raw log names the exact chain rejection reason
- Refresh the account sequence/number before re-broadcasting
- Increase gas limit or set gas price to meet the network minimum
- Re-check order parameters against dYdX chain validation rules
- Verify node status / chain is not halted for an upgrade
Example fix
// before: blind retry
client.broadcast_tx(tx).await?;
// after: inspect code/log and resync sequence
match client.broadcast_tx(tx.clone()).await {
Err(e) if e.to_string().contains("code=32") => { // sequence mismatch
tx_manager.resync_sequence().await?;
client.broadcast_tx(tx).await?;
}
r => r?,
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure sequence is fresh and gas is sufficient before broadcast tx_manager.refresh_account().await?; debug_assert!(tx.gas >= estimated_min_gas);
Try / catch
match client.broadcast_tx(tx).await {
Err(e) => {
let msg = e.to_string();
if msg.contains("code=32") { tx_manager.resync_sequence().await?; /* retry */ }
else if msg.contains("out of gas") || msg.contains("fee") { raise_gas_and_retry(); }
else { return Err(e); }
}
Ok(h) => Ok(h),
} Prevention
- Parse code and raw_log rather than treating all failures alike
- Keep account sequence synced, especially after restarts
- Set gas limit/price above current network minimums
- Monitor chain upgrade schedules that halt broadcasts
When it happens
Trigger: Any TX broadcast (order submit/cancel) where the chain returns tx_response.code != 0 — e.g. out-of-gas, wrong account sequence, under-minimum gas price, or rejected msg content.
Common situations: Gas price/limit misconfigured relative to network minimums; account sequence desync after a restart; submitting during chain halt or upgrades; malformed order params failing chain validation.
Related errors
- Transaction {} reverted on-chain
- Transaction not found
- Failed to start replacement transaction persistence: {e}
- Failed to retire replaced execution hash: {e}
- Failed to mark execution intent replaced: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/da677d746c1083c4.
Report an issue: GitHub.