## TL;DR
Exhausted retries mean the failure is consistent, not transient: the same error on every attempt. Read the error from the final attempt, fix the underlying cause in the op or its inputs, then re-execute. Adding more retries to a deterministic failure just burns compute slower.

```text
dagster op retry exhausted, run failed
```

## Use this when
- A run fails after using all configured retries.
- Every attempt shows the same error.
- Retries helped before but no longer do.

## Not for this skill when
- The op fails once with no retries configured. Add a retry policy first.
- Attempts show different errors. That is flakiness, not exhaustion.

## Steps
1. Read the final attempt's error and compare it across attempts. Note whether it is identical each time. Verify: deterministic versus flaky is decided
2. If identical, fix the cause: bad input, missing resource, broken dependency. Note the fix addresses the error. Verify: the root cause is addressed
3. If the errors differ, the failure is flaky: check downstream dependencies and resource contention. Note the flaky layer. Verify: the flaky layer is named
4. Tune the retry policy to the failure type: backoff for transient, few or zero retries for deterministic. Note the policy fits. Verify: retries match reality
5. Re-execute the run and confirm the op succeeds. Note the run is green. Verify: the fix is verified

## Variant phrasings
### dagster retry policy exhausted
The policy-shaped search.
### dagster op failed after retries
The outcome phrasing.

Compatibility: Dagster 1.x RetryPolicy on ops. Backoff and delay semantics are stable.

## Why it happens
Retries exist for transient failures: a momentarily unavailable API, a brief network blip. A deterministic bug fails identically on attempt one and attempt ten, and retries just delay the inevitable while consuming executor slots. Exhaustion is information: it tells you the failure survived multiple chances, so stop retrying and start fixing. The retry policy should encode what you believe about the failure, not hope.

## Edge cases / pitfalls
- RetryPolicy on the op versus the job can surprise: job-level retries re-run more than you expect. Know which level you set.
- Retries that partially succeed can double-write downstream. Make retried ops idempotent.
- max_retries counts attempts, not time. A fast-failing op burns all retries in seconds; add delay for transient causes.
- Backoff without jitter can synchronize retries across parallel ops into a thundering herd. Add jitter for shared dependencies.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_lpz5422a70ZEqAS9sUbY0A
