nats-io/nats-server · error
bad ack floor for consumer
Error message
bad ack floor for consumer
What it means
Sanity check in consumerMemStore.Update: the reported consumer-sequence AckFloor exceeds the Delivered consumer sequence, which is impossible in a consistent state (more messages acknowledged than delivered). It guards against persisting a corrupted or forged ConsumerState.
Source
Thrown at server/memstore.go:2762
}
lseq := ms.state.LastSeq
for _, db := range dbs {
// Skip if beyond our current state.
if first, _, _ := db.State(); first > lseq {
continue
}
db.Range(func(seq uint64) bool {
ms.removeMsg(seq, false)
return true
})
}
return nil
}
func (o *consumerMemStore) Update(state *ConsumerState) error {
// Sanity checks.
if state.AckFloor.Consumer > state.Delivered.Consumer {
return fmt.Errorf("bad ack floor for consumer")
}
if state.AckFloor.Stream > state.Delivered.Stream {
return fmt.Errorf("bad ack floor for stream")
}
// Copy to our state.
var pending map[uint64]*Pending
var redelivered map[uint64]uint64
if len(state.Pending) > 0 {
pending = make(map[uint64]*Pending, len(state.Pending))
for seq, p := range state.Pending {
pending[seq] = &Pending{p.Sequence, p.Timestamp}
if seq <= state.AckFloor.Stream || seq > state.Delivered.Stream {
return fmt.Errorf("bad pending entry, sequence [%d] out of range", seq)
}
}
}
if len(state.Redelivered) > 0 {View on GitHub (pinned to 3a66a489d2)
Solutions
- Inspect the consumer state being pushed (usually from replication or a state update API) for a bogus AckFloor
- Reset or recreate the consumer if its state is irrecoverably inconsistent
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/memstore.go:2762 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c2115bdb39658639.
Report an issue: GitHub.