← Blog Blog · Governance

Bad rows shouldn't reach the warehouse

When a row fails a quality check, you have two honest choices: stop the world, or set it aside. faucet-stream does both — as a per-check decision — and never silently drops data.

faucet-stream·August 25, 2026·~5 min read

Two bad options, and the one nobody should pick

A row violates a rule — a null where you require a value, a negative amount, a broken enum. There are three things a pipeline can do: abort the run, quarantine the row, or silently drop it. The third is the one that ruins your data quietly, and it's the one faucet-stream never does.

Quality checks decide, per rule, before the write

Quality is a stage in the movement path — it runs on each page before the sink sees it. Every check declares what happens on failure:

quality:
  checks:
    - { field: amount, rule: { gte: 0 }, on_failure: abort }
    - { field: email,  rule: not_null,        on_failure: quarantine }
  • abort — stop the run. Use it for violations that mean the whole batch is suspect.
  • quarantine — route the offending row to a dead-letter queue, and let the good rows through. The bad row is captured, not discarded.

Quarantine needs somewhere to go

A quarantine action requires a DLQ sink to be configured — otherwise the run is rejected at startup, not quietly turned into a drop. "Set the row aside" only means something if there's a side to set it on.

And because governance runs in a fixed order with masking first, a quarantined row carries the masked payload, not the raw one — a bad row never leaks a secret into the DLQ. (More on that ordering in the governance paper.)

Takeaway

Invalid data stays out of the target, valid data keeps flowing, and nothing vanishes without a trace. Abort when the batch is untrustworthy; quarantine when it's a few bad rows — and never pick the silent third option, because faucet won't offer it.

More on the blog, or read the documentation.

Get started

Your first pipeline runs in five minutes.

Install the CLI, scaffold a config, and move real data — nothing external to stand up.

curl -LsSf https://github.com/faucet-hq/faucet-stream/releases/latest/download/faucet-cli-installer.sh | sh
brew install faucet-hq/faucet-stream/faucet-cli