nautechsystems/nautilus_trader · error · anyhow::Error
Broadcast response does not contain tx_response
Error message
Broadcast response does not contain tx_response
What it means
broadcast_tx checks the broadcast response for the optional `tx_response` field; if absent the node returned no receipt for the submitted transaction and the library raises instead of fabricating a tx hash. This means the broadcast result itself is missing, distinct from a tx that executed and failed (code != 0).
Source
Thrown at crates/adapters/dydx/src/grpc/client.rs:496
/// 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.
pub async fn get_tx(&mut self, hash: &str) -> Result<Tx, anyhow::Error> {
let req = GetTxRequest {
hash: hash.to_string(),
};
let response = self.tx.get_tx(req).await?.into_inner();
if let Some(tx) = response.tx {
// Convert through bytes since the types are incompatibleView on GitHub (pinned to 18893faf8b)
Solutions
- Retry the broadcast; if using BROADCAST_MODE_ASYNC, consider SYNC to always receive a receipt.
- Switch to a healthier RPC endpoint.
- After a missing receipt, look up the tx by hash of the signed bytes later, since the tx may still have been committed.
- Check node rate limits / authentication requirements on the RPC provider.
Example fix
// before
let hash = client.broadcast_tx(&tx_bytes).await?;
// after: retry once with SYNC mode
let hash = match client.broadcast_tx(&tx_bytes).await {
Ok(h) => h,
Err(e) if e.to_string().contains("does not contain tx_response") => {
client.broadcast_tx_mode(&tx_bytes, BroadcastMode::Sync).await?
}
Err(e) => return Err(e),
}; Defensive patterns
Strategy: retry
Try / catch
match client.broadcast_tx(&tx_bytes).await {
Ok(hash) => Ok(hash),
Err(e) if e.to_string().contains("does not contain tx_response") => {
tokio::time::sleep(Duration::from_secs(1)).await;
client.broadcast_tx(&tx_bytes).await
}
Err(e) => Err(e),
} Prevention
- Prefer BROADCAST_MODE_SYNC so receipts are always returned
- Retry idempotently-safe broadcasts with backoff
- Record signed tx hashes so results can be looked up later if a receipt is lost
When it happens
Trigger: Calling broadcast_tx (sync/async mode) when the node accepts the connection but returns a BroadcastTxResponse with tx_response unset — node overload, dropped result, or proto mismatch.
Common situations: Broadcasting during node instability or maintenance; hitting a rate-limited public RPC; using a mode the node doesn't support so no receipt is generated.
Related errors
- {e}
- Transaction broadcast failed: code={}, log={}
- Failed to sign transaction: {e}
- Cannot create sign doc: {e}
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0b6964b4ebf2c09f.
Report an issue: GitHub.