{"record":{"id":"2576fc4cec37404b","repo":"nautechsystems/nautilus_trader","slug":"failed-to-start-copy-operation-e","errorCode":null,"errorMessage":"Failed to start COPY operation: {e}","messagePattern":"Failed to start COPY operation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/copy.rs","lineNumber":65,"sourceCode":"    ///\n    /// Returns an error if the COPY operation fails.\n    pub async fn copy_blocks(&self, chain_id: u32, blocks: &[Block]) -> anyhow::Result<()> {\n        if blocks.is_empty() {\n            return Ok(());\n        }\n\n        let copy_statement = \"\n            COPY block (\n                chain_id, number, hash, parent_hash, miner, gas_limit, gas_used, timestamp,\n                base_fee_per_gas, blob_gas_used, excess_blob_gas,\n                l1_gas_price, l1_gas_used, l1_fee_scalar\n            ) FROM STDIN WITH (FORMAT BINARY)\";\n\n        let mut copy_in = self\n            .pool\n            .copy_in_raw(copy_statement)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to start COPY operation: {e}\"))?;\n\n        // Write binary header\n        self.write_copy_header(&mut copy_in).await?;\n\n        // Write each block as binary data\n        for block in blocks {\n            self.write_block_binary(&mut copy_in, chain_id, block)\n                .await?;\n        }\n\n        // Write binary trailer\n        self.write_copy_trailer(&mut copy_in).await?;\n\n        // Finish the COPY operation\n        copy_in\n            .finish()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to finish COPY operation: {e}\"))?;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/copy.rs#L47-L83","documentation":"The blockchain cache inserts blocks using PostgreSQL `COPY ... FROM STDIN (FORMAT BINARY)` for bulk performance. This error wraps a failure of `copy_in_raw` — i.e. the COPY statement itself failed to start against the pool (connection issues, SQL error, or permissions). No block data has been written at this stage.","triggerScenarios":"`copy_blocks` at crates/adapters/blockchain/src/cache/copy.rs:65 calls `pool.copy_in_raw(copy_statement)` and the underlying tokio-postgres/tls layer returns an error — dead pooled connection, unreachable database, invalid credentials, or the target table missing.","commonSituations":"Database restarted or network blip while a pooled connection sits idle; wrong DSN/credentials in cache config; migrations not applied so the blocks table doesn't exist; user lacking COPY/INSERT privilege.","solutions":["Read the wrapped `e` message: fix the underlying cause (connection refused, auth failed, undefined table, etc.).","Verify database connectivity (`psql $DATABASE_URL`) and that schema migrations have created the target table.","Check the pool is healthy and connection limits/SSL settings are correct for the environment.","Retry the operation; for transient failures, add reconnect/backoff around `copy_blocks`."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"let conn_ok = sqlx::query(\"SELECT 1\").execute(&pool).await.is_ok();\nif !conn_ok { return Err(anyhow::anyhow!(\"database unreachable before COPY\")); }","typeGuard":null,"tryCatchPattern":"match copy_blocks(&cache, &blocks).await {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"Failed to start COPY\") => {\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        retry_with_backoff(|| copy_blocks(&cache, &blocks), 3).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Run migrations before starting cache ingestion.","Health-check the pool (SELECT 1) before bulk operations.","Set sane pool idle timeouts so connections aren't dead on reuse.","Grant the DB user INSERT on target tables."],"tags":["postgres","database","copy","bulk-insert"],"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"}