Not Null Check Examples
Three real-world scenarios that show how the Not Null check is typically used in production: enforcing mandatory customer columns, requiring a settlement reference on completed payments with a filter, and auditing a legacy column mid-backfill. The first two run at 100% coverage and report Record Anomalies; the third lowers coverage and reports a Shape Anomaly instead.
The situation: Every row in the customers table must carry an identifier and a creation timestamp. Rows missing either one come from a partial import that ran without the header mapping, and they break joins and cohort reporting downstream.
Check configuration
| Field | Value |
|---|---|
| Rule | Not Null |
| Fields | c_custkey, created_at |
| Filter | (none) |
| Custom Anomaly Description | Off |
| Coverage | 100% |
| Owner | (check creator) |
| Anomaly Assignee | (CRM Data team) |
| Description | Customer identifier and creation timestamp must always be populated. |
| Tags | completeness, customers |
| Additional Metadata | jira: DATA-9001 |
| Status | Active |
Payload
{
"description": "Customer identifier and creation timestamp must always be populated.",
"rule": "notNull",
"fields": ["c_custkey", "created_at"],
"container_id": 145,
"coverage": 1,
"filter": null,
"properties": {},
"tags": ["completeness", "customers"],
"additional_metadata": {"jira": "DATA-9001"},
"anomaly_message_field": null,
"template_id": null,
"status": "Active",
"owner_id": 7,
"default_anomaly_assignee_id": 12
}
Sample Data
| c_custkey | created_at | c_name |
|---|---|---|
| 1001 | 2026-02-03 10:11:00 | Acme Ltd |
| 1002 | (null) | Beta SA |
| (null) | 2026-02-05 09:00:00 | Gamma Inc |
| 1004 | 2026-02-06 14:30:00 | Delta Co |
What gets flagged
Row 1002 is missing its creation timestamp and the third row is missing its identifier. Both fail, because the two fields are asserted together. Coverage is 100%, so each failing row is reported as a Record Anomaly, with the empty cell highlighted.
Record Anomaly
The field 'created_at' has a null or missing value
Flowchart
graph TD
A["No filter, evaluate all rows"] --> B["Read c_custkey and created_at"]
B --> C{"Are both fields populated?"}
C -->|Yes| D["Row passes"]
C -->|No| E["Flag row.<br/>Record Anomaly per failing row."]
Equivalent SQL
The situation: Payments in the completed state must carry a settlement reference. Pending and failed payments legitimately have none, so they are excluded with a filter.
Check configuration
| Field | Value |
|---|---|
| Rule | Not Null |
| Fields | settlement_ref |
| Filter | status = 'completed' |
| Custom Anomaly Description | Off |
| Coverage | 100% |
| Owner | (check creator) |
| Anomaly Assignee | (Payments Engineering) |
| Description | Completed payments must carry a settlement reference. |
| Tags | payments, completeness |
| Additional Metadata | jira: DATA-9044 |
| Status | Active |
Payload
{
"description": "Completed payments must carry a settlement reference.",
"rule": "notNull",
"fields": ["settlement_ref"],
"container_id": 512,
"coverage": 1,
"filter": "status = 'completed'",
"properties": {},
"tags": ["payments", "completeness"],
"additional_metadata": {"jira": "DATA-9044"},
"anomaly_message_field": null,
"template_id": null,
"status": "Active",
"owner_id": 7,
"default_anomaly_assignee_id": 15
}
Sample Data (filtered to status = 'completed')
| payment_id | status | settlement_ref |
|---|---|---|
| P-001 | completed | STL-99812 |
| P-002 | completed | (null) |
| P-003 | completed | STL-99814 |
Why the filter matters
The filter runs before the evaluation, so pending and failed payments, which have no reference yet, are never tested. Only completed payments are evaluated.
What gets flagged
P-002 is marked completed but carries no settlement reference, which means the settlement callback never landed. Coverage is 100%, so the failure is reported as a Record Anomaly, and the message ends with the filter that scoped the evaluation.
Record Anomaly
The field 'settlement_ref' has a null or missing value [filter: status = 'completed']
Flowchart
graph TD
A["Apply filter: status = 'completed'"] --> B["Read settlement_ref"]
B --> C{"Is settlement_ref populated?"}
C -->|Yes| D["Row passes"]
C -->|No| E["Flag row.<br/>Anomaly message ends with<br/>[filter: status = 'completed']"]
Equivalent SQL
The situation: A newly added region_code column is being backfilled across historical rows. Until the job finishes, a small fraction of rows is expected to be empty, so the check tolerates up to 0.5% failures while still catching a backfill that stalls.
Check configuration
| Field | Value |
|---|---|
| Rule | Not Null |
| Fields | region_code |
| Filter | (none) |
| Custom Anomaly Description | Off |
| Coverage | 99.5% |
| Owner | (check creator) |
| Anomaly Assignee | (Data Platform team) |
| Description | Region code must be populated on every account. |
| Tags | completeness, backfill |
| Additional Metadata | jira: DATA-9088 |
| Status | Active |
Payload
{
"description": "Region code must be populated on every account.",
"rule": "notNull",
"fields": ["region_code"],
"container_id": 733,
"coverage": 0.995,
"filter": null,
"properties": {},
"tags": ["completeness", "backfill"],
"additional_metadata": {"jira": "DATA-9088"},
"anomaly_message_field": null,
"template_id": null,
"status": "Active",
"owner_id": 7,
"default_anomaly_assignee_id": 41
}
Sample Data
| account_id | region_code | migrated |
|---|---|---|
| A-01 | EMEA | true |
| A-02 | (null) | false |
| A-03 | (null) | false |
| A-04 | LATAM | true |
What gets flagged
Accounts A-02 and A-03 have not been reached by the backfill yet. Only 50% of the rows pass, which is below the 99.5% coverage threshold, so the check reports a single Shape Anomaly for the dataset with a sample of the offending rows. Coverage below 100% does not produce Record Anomalies.
Shape Anomaly
For the field 'region_code', 50.000% of 4 records (2) have null or missing values
Flowchart
graph TD
A["No filter, evaluate all rows"] --> B["Read region_code"]
B --> C{"Is region_code populated?"}
C -->|Yes| D["Row passes"]
C -->|No| E["Flag row.<br/>Passing rate falls below the 99.5%<br/>coverage, so one Shape Anomaly is reported."]
Equivalent SQL
See Also
-
How It Works
The complete reference: definition, field scope, multi-field behavior, empty strings, arrays, filter behavior, and coverage.
-
Anomaly Reporting
The anomaly messages the check produces, what the numbers mean, Source Records highlighting, and Custom Anomaly Description.
-
Best Practices
Guidelines for choosing mandatory fields, handling empty strings, pairing rules, and keeping the signal clean.
-
Permissions
The team permission each action needs: view, create, edit, archive, restore, and delete.