etcd-io/etcd · error

unexpected filter in delete

Error message

unexpected filter in delete

What it means

OpDelete rejects WithFilterDelete and WithFilterPut. Those flags tell a range read to omit delete/put events (or KV entries) from results; a delete range produces no such event stream to filter. The validation switch sees ret.filterDelete || ret.filterPut set and panics with "unexpected filter in delete".

Source

Thrown at client/v3/op.go:293

	switch {
	case ret.leaseID != 0:
		panic("unexpected lease in delete")
	case ret.limit != 0:
		panic("unexpected limit in delete")
	case ret.rev != 0:
		panic("unexpected revision in delete")
	case ret.sort != nil:
		panic("unexpected sort in delete")
	case ret.serializable:
		panic("unexpected serializable in delete")
	case ret.countOnly:
		panic("unexpected countOnly in delete")
	case ret.minModRev != 0, ret.maxModRev != 0:
		panic("unexpected mod revision filter in delete")
	case ret.minCreateRev != 0, ret.maxCreateRev != 0:
		panic("unexpected create revision filter in delete")
	case ret.filterDelete, ret.filterPut:
		panic("unexpected filter in delete")
	case ret.createdNotify:
		panic("unexpected createdNotify in delete")
	}
	return ret
}

// OpPut returns "put" operation based on given key-value and operation options.
func OpPut(key, val string, opts ...OpOption) Op {
	ret := Op{t: tPut, key: []byte(key), val: []byte(val)}
	ret.applyOpts(opts)
	switch {
	case ret.end != nil:
		panic("unexpected range in put")
	case ret.limit != 0:
		panic("unexpected limit in put")
	case ret.rev != 0:
		panic("unexpected revision in put")
	case ret.sort != nil:

View on GitHub (pinned to f744d457f4)

Solutions

  1. Remove WithFilterDelete/WithFilterPut from Delete calls; they only belong on Get and Watch.
  2. If the goal was to delete only put events' keys, that filtering must happen client-side: Get the keys, then delete them.

Example fix

// before
_, err := cli.Delete(ctx, stateKey, clientv3.WithFilterPut()) // panics

// after
_, err := cli.Delete(ctx, stateKey)
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: clientv3.OpDelete("/k", clientv3.WithFilterPut()); forwarding watch or Get options (used to strip event types) into an invalidation Delete; shared option structs covering reads, watches, and writes.

Common situations: Event-pipeline code that already filters puts on the watch side and reuses the option bundle when clearing state; cache invalidation helpers mixing watch options with delete calls.

Related errors


AI-assisted analysis of etcd-io/etcd@f744d457f4 (2026-08-15). Data as JSON: /api/errors/47b59d59bdfc6b06. Report an issue: GitHub.