nautechsystems/nautilus_trader · error · anyhow::Error

Failed to activate verification schema: {e}

Error message

Failed to activate verification schema: {e}

What it means

Thrown when one of the DDL statements that activates the verification schema fails: creating the `execution_verification_append_only()` trigger function or its BEFORE UPDATE OR DELETE triggers on the decision and finalized-header tables, or upserting the schema-version marker row. It wraps the sqlx error from executing each statement in the migration transaction.

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:4587

            "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()
            ",
            "DROP TRIGGER IF EXISTS execution_finalized_header_append_only \
             ON execution_verified_finalized_header",
            "
            CREATE TRIGGER execution_finalized_header_append_only
            BEFORE UPDATE OR DELETE ON execution_verified_finalized_header
            FOR EACH STATEMENT EXECUTE FUNCTION execution_verification_append_only()
            ",
        ] {
            sqlx::query(statement)
                .execute(&mut *transaction)
                .await
                .map_err(|e| anyhow::anyhow!("Failed to activate verification schema: {e}"))?;
        }
        sqlx::query(
            "
            INSERT INTO execution_schema_version (component, version)
            VALUES ('evm_execution_verification', $1)
            ON CONFLICT (component) DO UPDATE SET version = EXCLUDED.version
            WHERE execution_schema_version.version <= EXCLUDED.version
            ",
        )
        .bind(VERIFICATION_SCHEMA_VERSION)
        .execute(&mut *transaction)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to activate verification schema: {e}"))?;

        transaction
            .commit()
            .await
            .map_err(|e| anyhow::anyhow!("Failed to commit verification migration: {e}"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the wrapped sqlx message for the failing statement and Postgres error code
  2. Grant the database role ownership or DDL (CREATE) privileges on the schema/tables
  3. Ensure the execution verification tables were created before this activation step (run the table-creation migration first)
  4. Check pg_locks for concurrent DDL sessions blocking the trigger creation

Example fix

// before: role lacking DDL rights
CREATE USER app WITH SELECT, INSERT, UPDATE, DELETE ON ALL TABLES;
// after: allow schema activation
GRANT CREATE ON SCHEMA public TO app;
GRANT ALL ON ALL TABLES IN SCHEMA public TO app;
Defensive patterns

Strategy: try-catch

Validate before calling

let ddl_ok: bool = sqlx::query_scalar(
    "SELECT has_schema_privilege(current_user, 'public', 'CREATE')")
    .fetch_one(&pool).await?;
if !ddl_ok { return Err(anyhow::anyhow!("database role lacks DDL privileges for schema activation")); }

Try / catch

match db.ensure_execution_verification_schema().await {
    Err(e) if e.to_string().contains("Failed to activate verification schema") => {
        // DDL step failed: check privileges, table existence, blocking locks before retrying
        return Err(e.context("schema activation requires DDL privileges and pre-created tables"));
    }
    other => other,
}

Prevention

When it happens

Trigger: Executing `CREATE OR REPLACE FUNCTION ... RETURNS TRIGGER` or `CREATE TRIGGER ...` during `ensure_execution_verification_schema`; failures include the base tables not existing yet, missing ownership/DDL privileges, or the version upsert INSERT failing on a malformed `execution_schema_version` table.

Common situations: Connecting as a role with only read/write but no CREATE privileges; an older database where tables were created by a different migration path; a DBA-managed schema where triggers are disallowed; concurrent DDL locks held by another session.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/c93b3776671acdf2. Report an issue: GitHub.