{"record":{"id":"330f9c2a362bf316","repo":"nautechsystems/nautilus_trader","slug":"failed-to-write-block-data-e","errorCode":null,"errorMessage":"Failed to write block data: {e}","messagePattern":"Failed to write block data: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/copy.rs","lineNumber":432,"sourceCode":"            let l1_gas_used_bytes = (l1_gas_used as i64).to_be_bytes();\n            row_data.write_all(&(l1_gas_used_bytes.len() as i32).to_be_bytes())?;\n            row_data.write_all(&l1_gas_used_bytes)?;\n        } else {\n            row_data.write_all(&(-1i32).to_be_bytes())?; // NULL value\n        }\n\n        if let Some(l1_fee_scalar) = block.l1_fee_scalar {\n            let l1_fee_scalar_bytes = (l1_fee_scalar as i64).to_be_bytes();\n            row_data.write_all(&(l1_fee_scalar_bytes.len() as i32).to_be_bytes())?;\n            row_data.write_all(&l1_fee_scalar_bytes)?;\n        } else {\n            row_data.write_all(&(-1i32).to_be_bytes())?; // NULL value\n        }\n\n        copy_in\n            .send(row_data)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to write block data: {e}\"))?;\n        Ok(())\n    }\n\n    /// Writes a single pool swap in PostgreSQL binary format.\n    ///\n    /// Each row in binary format consists of:\n    /// - 2-byte field count\n    /// - For each field: 4-byte length followed by data (or -1 for NULL)\n    async fn write_pool_swap_binary(\n        &self,\n        copy_in: &mut sqlx::postgres::PgCopyIn<sqlx::pool::PoolConnection<sqlx::Postgres>>,\n        chain_id: u32,\n        swap: &PoolSwap,\n    ) -> anyhow::Result<()> {\n        use std::io::Write;\n        let mut row_data = Vec::new();\n\n        row_data.write_all(&19u16.to_be_bytes())?;","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/copy.rs#L414-L450","documentation":"write_block_binary serializes one Block into PostgreSQL COPY BINARY row format and sends it with PgCopyIn::send; a send failure is wrapped as 'Failed to write block data'. Because the error propagates via `?`, the whole copy_blocks batch aborts. This is a mid-stream write failure — transport error or the server having already rejected the COPY session.","triggerScenarios":"Connection loss while streaming a large block batch, server abort of the COPY (e.g. previous row triggered an error surfaced on the next send), or serialization code writing bytes inconsistent with the declared column list.","commonSituations":"Multi-thousand-block backfills across an unreliable network/VPN; DB restart mid-backfill; after a migration changed the block table but write_block_binary still writes the old field layout.","solutions":["Retry copy_blocks with a smaller batch size to isolate the failing block and survive transient drops","Compare the fields written by write_block_binary to the COPY column list for block after recent migrations","Check DB server logs for why the COPY session aborted","Enable connection health checks (test_before_acquire) and re-run the backfill"],"exampleFix":"// before\nhandler.copy_blocks(chain_id, &all_blocks).await?;\n// after\nfor chunk in all_blocks.chunks(500) {\n    handler.copy_blocks(chain_id, chunk).await?;\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let result = handler.copy_blocks(chain_id, &blocks).await;\nmatch result {\n    Err(e) if e.to_string().contains(\"Failed to write block data\") => {\n        tokio::time::sleep(Duration::from_secs(5)).await;\n        handler.copy_blocks(chain_id, &blocks).await?; // retry whole batch; COPY is atomic\n    }\n    other => other?,\n}","preventionTips":["Chunk block batches (e.g. 500) so retries are cheap","Monitor network stability for long backfills","Recheck write_block_binary field layout after schema migrations","Check server logs at the first sign of mid-stream aborts"],"tags":["postgres","copy-binary","streaming"],"backgroundTag":"database-write-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}