etcd-io/etcd · error
unexpected create revision filter in watch
Error message
unexpected create revision filter in watch
What it means
OpWatch panics with 'unexpected create revision filter in watch' when WithMinCreateRev or WithMaxCreateRev is applied to a watch. Create-revision filters narrow range results by when keys were created; watches have no such filtering, so OpWatch's validation switch rejects them with this panic before any stream opens.
Source
Thrown at client/v3/op.go:355
func OpWatch(key string, opts ...OpOption) Op {
ret := Op{t: tRange, key: []byte(key)}
ret.applyOpts(opts)
switch {
case ret.leaseID != 0:
panic("unexpected lease in watch")
case ret.limit != 0:
panic("unexpected limit in watch")
case ret.sort != nil:
panic("unexpected sort in watch")
case ret.serializable:
panic("unexpected serializable in watch")
case ret.countOnly:
panic("unexpected countOnly in watch")
case ret.minModRev != 0, ret.maxModRev != 0:
panic("unexpected mod revision filter in watch")
case ret.minCreateRev != 0, ret.maxCreateRev != 0:
panic("unexpected create revision filter in watch")
}
return ret
}
func (op *Op) applyOpts(opts []OpOption) {
for _, opt := range opts {
opt(op)
}
}
// OpOption configures Operations like Get, Put, Delete.
type OpOption func(*Op)
// WithLease attaches a lease ID to a key in 'Put' request.
func WithLease(leaseID LeaseID) OpOption {
return func(op *Op) { op.leaseID = leaseID }
}
View on GitHub (pinned to f744d457f4)
Solutions
- Remove WithMinCreateRev/WithMaxCreateRev from the watch call
- Filter create revisions client-side on incoming watch events using Kv.CreateRevision, or seed state with the filtered Get first
- Maintain distinct builders for listing options and watch options
- Add tests constructing all watches used by the application to fail fast in CI
Example fix
// before
op := clientv3.OpWatch("k", clientv3.WithMinCreateRev(1000))
// after
wop := clientv3.OpWatch("k", clientv3.WithPrefix())
// filter in handler: if ev.Kv.CreateRevision >= 1000 { ... } Defensive patterns
Strategy: validation
Validate before calling
// Filter created-revision client-side in the event handler:
for ev := range wch {
if ev.Kv.CreateRevision >= minCreateRev {
handle(ev)
}
} Prevention
- Create-revision filters are query-only
- Apply such filters in watch handlers client-side
- Keep listing options away from watch construction
When it happens
Trigger: Calling clientv3.OpWatch(key, clientv3.WithMinCreateRev(n)) or WithMaxCreateRev(n); reusing options from a listing query that filters keys by creation time when subscribing to the same keys; unified option structs mapped onto every operation type.
Common situations: 'Keys created since X' audit features that both list (filtered Get) and subscribe; copy-paste between adjacent listing and watching code; refactors that collapsed option handling into one helper.
Related errors
- unexpected mod revision filter in watch
- unexpected mod revision filter in put
- unexpected create revision filter in put
- unexpected lease in watch
- unexpected limit in watch
AI-assisted analysis of etcd-io/etcd@f744d457f4 (2026-08-15).
Data as JSON: /api/errors/1567d68cf8a84108.
Report an issue: GitHub.