t8y2/dbx · error
ETCD_COMPACTED
ETCD_COMPACTED
Error message
ETCD_COMPACTED: requested history was compacted at revision
What it means
The initial Get that anchors the history query (WithRev at endRevision) failed with etcd's ErrCompacted, meaning the requested revision precedes the cluster's compaction boundary and its MVCC history has been discarded. The library then probes the compaction revision with a rev-1 watch and reports it in the message; if the probe fails it falls back to the generic ETCD_COMPACTED message (error 335).
Source
Thrown at agents/drivers/etcd-go/history.go:67
if limit < 1 {
limit = 1
}
if limit > historyLimitMax {
limit = historyLimitMax
}
requestedEnd := longOrNull(params, "endRevision")
ctx, cancel := context.WithTimeout(context.Background(), rpcTimeoutSeconds*time.Second)
latestOptions := []clientv3.OpOption{}
if requestedEnd != nil && *requestedEnd > 0 {
latestOptions = append(latestOptions, clientv3.WithRev(*requestedEnd))
}
latest, err := client.Get(ctx, key, latestOptions...)
cancel()
if err != nil {
if errors.Is(err, rpctypes.ErrCompacted) {
if revision, ok := compactedRevisionOf(client, key); ok {
return nil, errors.New("ETCD_COMPACTED: requested history was compacted at revision " + longString(revision))
}
return nil, errors.New("ETCD_COMPACTED: requested history was compacted")
}
return nil, err
}
var endRevision int64
if requestedEnd != nil {
endRevision = *requestedEnd
} else {
endRevision = latest.Header.Revision
}
var targetKeyRevision int64
if len(latest.Kvs) == 0 {
targetKeyRevision = endRevision
} else {
targetKeyRevision = latest.Kvs[0].ModRevision
}
requestedStart := longOrNull(params, "startRevision")View on GitHub (pinned to c0390bff16)
Solutions
- Re-run history without endRevision (or with a recent one) so the query anchors at the current revision.
- Increase etcd's --auto-compaction-retention to retain more history.
- Clamp startRevision to the compact revision reported; never query below it.
- Persist and use the revision reported in the error message as the new lower bound for future queries.
Example fix
// before
result, err := session.history(map[string]json.RawMessage{"endRevision": json.RawMessage("50")}) // compacted
// after
// omit stale endRevision, or use the reported compact revision + 1
result, err := session.history(map[string]json.RawMessage{}) Defensive patterns
Strategy: fallback
Validate before calling
compactRev := lastKnownCompactRevision() // track from prior ETCD_COMPACTED errors
if endRevision != nil && *endRevision <= compactRev {
endRevision = nil // anchor at latest instead of a compacted revision
} Try / catch
result, err := session.history(params)
if err != nil {
if strings.HasPrefix(err.Error(), "ETCD_COMPACTED") {
params = dropEndRevision(params) // fall back to latest-revision anchor
result, err = session.history(params)
}
if err != nil { return nil, err }
} Prevention
- Track the last known compact revision and clamp endRevision/startRevision above it.
- Increase etcd --auto-compaction-retention to retain queried history windows.
- Avoid caching old revision bookmarks across long periods.
- Handle the ETCD_COMPACTED prefix explicitly and retry anchored at the latest revision.
When it happens
Trigger: Calling history with endRevision older than the cluster's current compact revision, or with a very old default window (10000 revisions) on a cluster that compacts aggressively; the Get at that revision returns rpctypes.ErrCompacted.
Common situations: Replaying an old snapshot/audit query after the etcd server auto-compacted; long-lived clients with stale revision bookmarks; clusters with short --auto-compaction-retention and infrequent history queries.
Related errors
- ETCD_HISTORY_FAILED
- ETCD_INVALID_REVISION
- user is required
- Not connected
- Client certificate and key must be provided together
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/59cb7561bfde6fc4.
Report an issue: GitHub.