Skip to content
Latchkey

dbt source freshness "source ... is stale" in CI

dbt checked how long ago a source table was last loaded and it exceeds your warn_after or error_after threshold, so dbt source freshness reports the source as stale and returns an error state.

What this error means

A dbt source freshness step reports a source as ERROR or WARN because its max loaded-at timestamp is older than the configured window, for example many hours old.

dbt
1 of 1 START freshness of shop.raw_orders
1 of 1 ERROR STALE freshness of shop.raw_orders ......... [ERROR in 0.42s]
  Source shop.raw_orders is 27 hours old, error_after: 24 hours

Common causes

The upstream load genuinely lagged

The ingestion that populates the source did not run or is delayed, so the newest row is older than the freshness threshold.

CI checks freshness against a static fixture

In CI the source is a fixed seed or snapshot with an old timestamp, so freshness always trips even though production is fine.

How to fix it

Fix or wait on the upstream load

  1. Confirm the ingestion job that loads the source succeeded recently.
  2. Re-run the load if it lagged, then re-check freshness.
  3. Escalate the pipeline delay if freshness is a real production issue.
Terminal
dbt source freshness --select source:shop.raw_orders

Scope freshness out of PR CI

Freshness of live sources is a scheduled concern, not a PR concern. Run freshness on schedule against production and skip it on PR builds that use fixtures.

.github/workflows/ci.yml
# run freshness only on the nightly schedule, not on PRs
if: github.event_name == 'schedule'

How to prevent it

  • Run source freshness on a schedule against live data, not on PR fixtures.
  • Set warn_after/error_after to realistic load cadences.
  • Alert on freshness failures separately from test failures.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →