FREE STUDY NOTES · DBX-DEP

Lakeflow Pipelines expectations: warn, drop, fail and quarantine

What each expectation action does to a bad record, and how quarantine is built.

From Ultra Transcenders DBX-DEP by Tony Rough (coming December 2026)

Expectations are named SQL Boolean checks applied to each record as it passes through a query. There are three built-in actions; quarantine is a pattern built from them, not a fourth action.

Action SQL Python Result Metrics
warn (default) EXPECT dp.expect Invalid rows are written to the target Yes
drop EXPECT ... ON VIOLATION DROP ROW dp.expect_or_drop Invalid rows are removed before the write; the count is logged Yes
fail EXPECT ... ON VIOLATION FAIL UPDATE dp.expect_or_fail The update fails and rolls back; manual intervention needed No, since the update fails
CREATE OR REFRESH STREAMING TABLE customers(
  CONSTRAINT valid_age EXPECT (age BETWEEN 0 AND 120),
  CONSTRAINT valid_id EXPECT (id IS NOT NULL)
    ON VIOLATION DROP ROW
) AS SELECT * FROM STREAM(raw_customers);

The constraint must be valid SQL and cannot include custom Python functions, external service calls or subqueries that reference other tables. Names must be unique within a dataset, and they can be reused across datasets.

In Python, expect_all, expect_all_or_drop and expect_all_or_fail take a dictionary of name to constraint and apply one action to the group. SQL can hold several expectations on a dataset but has no way to group them or load them dynamically. Rules can live in a Delta table or Python module, read by a helper function.

Choosing the action is a per-constraint decision, and the production checklist gives the rule: fail for conditions that should stop everything, such as a broken primary key; drop for records that can be discarded, with a quarantine table capturing what was dropped; warn only where someone actually watches the trend. Figure 5.2 shows what each action does to an invalid row, and how quarantine is built.

Records pass a named SQL check and meet one of three actions: warn writes invalid rows to the target, drop removes them and logs a count, and fail rolls back the update without metrics. Below, the quarantine pattern uses a warn expectation and a computed is_quarantined column, with one view each for valid and invalid rows.
Figure 5.2: The three built-in expectation actions, and quarantine as a pattern built from warn.

The effect of a failed expectation

The scope of a failure depends on the pipeline mode.

Pipeline mode What expect_or_fail stops
Triggered Only that flow, which rolls back; parallel flows carry on
Continuous The flow and all dependent flows, with a message explaining why

The EXPECTATION_VIOLATION error reports the violated expectation and, for many queries, the input record. Metrics are not recorded for fail, so read the message and fix the pipeline code before rerunning.

Expectations enforce quality, not orchestration. A validation table, such as a materialized view that compares row counts under expect_or_fail, does not gate its readers: a downstream dataset does not wait for its result. To stop downstream work when validation fails, put the validation and the downstream work in separate pipelines and link them with task dependencies in a job, as covered in “Lakeflow Jobs”.

The quarantine pattern

Quarantine keeps bad rows for inspection without failing or losing them. A warn expectation records metrics, a computed column marks each row, and views split the two paths.

from pyspark import pipelines as dp
from pyspark.sql.functions import expr

rules = {
    "valid_pickup": "(pickup_zip IS NOT NULL)",
    "valid_dropoff": "(dropoff_zip IS NOT NULL)",
}
bad = "NOT({0})".format(" AND ".join(rules.values()))

@dp.table(temporary=True, partition_cols=["is_quarantined"])
@dp.expect_all(rules)
def trips_checked():
    return (
        spark.readStream.table("raw_trips")
        .withColumn("is_quarantined", expr(bad))
    )

@dp.view
def valid_trips():
    return spark.read.table("trips_checked").filter(
        "is_quarantined=false"
    )

@dp.view
def invalid_trips():
    return spark.read.table("trips_checked").filter(
        "is_quarantined=true"
    )

Where expectations do not reach

Common trap: Using expect_or_drop when the bad rows may be needed later - dropped rows are gone and only a count is logged, so use the quarantine pattern to keep them.

Common trap: Relying on a validation table with expect_or_fail to block downstream tables in the same pipeline - in a triggered pipeline other flows continue to update, so the gate must be a job dependency between separate pipelines.

Get the whole book

This note is one section of Ultra Transcenders DBX-DEP: Databricks Data Engineer Professional, an independent study guide that explains every topic the exam covers by technology, with comparison tables, diagrams and the common traps, plus a glossary linked to the Databricks documentation.

Amazon.co.ukKindle: coming soonPaperback: coming soon
Amazon.comKindle: coming soonPaperback: coming soon

Due on Amazon in December 2026, in Kindle and paperback editions.

About the book · DBX-DEP terms in the glossary · All DBX-DEP study notes

More DBX-DEP study notes