nautechsystems/nautilus_trader · error · anyhow::Error
Failed to persist connect verification: {e}
Error message
Failed to persist connect verification: {e} What it means
Thrown while persisting a connect-verification decision row into the `execution_verification_decision` table inside the execution verification schema migration transaction. The library wraps the underlying sqlx/Postgres error so callers get context about which migration step failed. The insert itself is idempotent-looking append-only evidence written once per (revision, decision index).
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:4557
NULL, NULL, 'connect', $1, $2, $3, $4, $5, $6, $7, $8,
'all_valid', $9, $10, 'verified', $11
)
",
)
.bind(decision.read_class)
.bind(height_start)
.bind(height_end)
.bind(bootstrap.manifest_version)
.bind(bootstrap.manifest_digest)
.bind(bootstrap.provider_ids)
.bind(bootstrap.operator_ids)
.bind(bootstrap.failure_domain_ids)
.bind(&decision.normalized_value_digest)
.bind(revision)
.bind(transition_key)
.execute(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to persist connect verification: {e}"))?;
}
for statement in [
"
CREATE OR REPLACE FUNCTION execution_verification_append_only()
RETURNS TRIGGER AS $$
BEGIN
RAISE EXCEPTION 'Execution verification evidence is append-only';
END;
$$ LANGUAGE plpgsql
",
"DROP TRIGGER IF EXISTS execution_verification_decision_append_only \
ON execution_verification_decision",
"
CREATE TRIGGER execution_verification_decision_append_only
BEFORE UPDATE OR DELETE ON execution_verification_decision
FOR EACH STATEMENT EXECUTE FUNCTION execution_verification_append_only()
",View on GitHub (pinned to 18893faf8b)
Solutions
- Read the inner sqlx error in the message to identify the exact DB failure
- Run the schema migrations / check `execution_schema_version` to confirm the verification schema exists at the expected version
- Check for concurrent instances running the migration against the same database and ensure only one bootstrap at a time
- Verify Postgres connectivity and that the user has INSERT privileges on execution_verification_decision
Example fix
// before: connecting to a stale/partially migrated DB and hitting the error
Database::connect(pool).await?;
// after: verify schema version before bootstrapping
let version: Option<i16> = sqlx::query_scalar(
"SELECT version FROM execution_schema_version WHERE component = 'evm_execution_verification'")
.fetch_optional(&pool).await?;
assert!(version.is_none() || version == Some(VERIFICATION_SCHEMA_VERSION)); Defensive patterns
Strategy: try-catch
Validate before calling
let ok: bool = sqlx::query_scalar(
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'execution_verification_decision')")
.fetch_one(&pool).await?;
if !ok { run_table_migration_first()?; } Try / catch
match ensure_verification_schema(&db).await {
Err(e) if e.to_string().contains("Failed to persist connect verification") => {
log::error!("verification write failed: {e:#}"); // inspect root-cause chain, check schema/privileges, retry bootstrap
}
Err(e) => return Err(e),
Ok(()) => {}
} Prevention
- Run schema migrations before application bootstrap and gate startup on them
- Grant the app role INSERT on all execution_* tables
- Ensure only one instance performs migration on a database at once (advisory lock)
- Monitor Postgres connectivity during startup
When it happens
Trigger: `ensure_execution_verification_schema` runs during database bootstrap and any of the per-decision INSERTs fails: schema/table missing, column type mismatch (e.g. height exceeding BIGINT already rejected earlier, but digest/manifest type mismatch possible), constraint violation on transition_key (duplicate revision), or connection dropped mid-transaction.
Common situations: Upgrading an older database where the table schema predates a new column; a concurrent migration running on the same database causing unique violations on transition_key; network interruption between app and Postgres during startup; running against a non-Postgres or partially migrated database.
Related errors
- Failed to load active execution intent: {e}
- Failed to start replacement transaction persistence: {e}
- Failed to lock active execution intent {intent_id}: {e}
- Active execution intent {intent_id} was not found
- Failed to retire replaced execution hash: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4fc1e4d7a1ff0ebd.
Report an issue: GitHub.