nats-io/nats-server · error · ApiError
max_batch must not be negative
Error message
max_batch must not be negative
What it means
A JetStream pedantic validation error thrown when MaxRequestBatch (the max number of messages a pull request may batch) is negative. Batch sizes are counts and cannot be negative; in pedantic mode the server refuses the config rather than clamping it to 0 (server default). Thrown from server/consumer.go:634 during consumer create/update validation.
Source
Thrown at server/consumer.go:634
}
config.MaxDeliver = -1
}
// Setup zero defaults.
if config.MaxWaiting < 0 {
if pedantic {
return NewJSPedanticError(errors.New("max_waiting must not be negative"))
}
config.MaxWaiting = 0
}
if config.MaxAckPending < -1 {
if pedantic {
return NewJSPedanticError(errors.New("max_ack_pending must be set to -1"))
}
config.MaxAckPending = -1
}
if config.MaxRequestBatch < 0 {
if pedantic {
return NewJSPedanticError(errors.New("max_batch must not be negative"))
}
config.MaxRequestBatch = 0
}
if config.MaxRequestExpires < 0 {
if pedantic {
return NewJSPedanticError(errors.New("max_expires must not be negative"))
}
config.MaxRequestExpires = 0
}
if config.MaxRequestMaxBytes < 0 {
if pedantic {
return NewJSPedanticError(errors.New("max_bytes must not be negative"))
}
config.MaxRequestMaxBytes = 0
}
if config.Heartbeat < 0 {
if pedantic {
return NewJSPedanticError(errors.New("idle_heartbeat must not be negative"))View on GitHub (pinned to 3a66a489d2)
Solutions
- Set MaxRequestBatch to a positive integer (e.g. 25_000) or 0 to use the server default.
- Clamp computed values: if v < 0 { v = 0 } before assigning to MaxRequestBatch.
- Remove any explicit negative value from consumer config YAML/JSON or CLI flags.
- Run config.Validate(true) client-side before the request to surface it early.
Example fix
// before
batchLimit := configuredBatch - overage // -3
cc := nats.ConsumerConfig{MaxRequestBatch: batchLimit}
// after
if batchLimit < 0 { batchLimit = 0 }
cc := nats.ConsumerConfig{MaxRequestBatch: batchLimit} Defensive patterns
Strategy: validation
Validate before calling
if cfg.MaxRequestBatch < 0 { return errors.New("max_batch must not be negative") } Try / catch
if _, err := js.AddConsumer(stream, &cc); err != nil && strings.Contains(err.Error(), "max_batch must not be negative") {
cc.MaxRequestBatch = 0
_, err = js.AddConsumer(stream, &cc)
} Prevention
- Use 0, not -1, to signal 'server default' for MaxRequestBatch.
- Clamp any computed batch limits to >= 0 before assignment.
- Validate configs client-side with Validate(true) in tests and at startup.
When it happens
Trigger: ConsumerConfig.MaxRequestBatch < 0 passed to consumer creation/update with pedantic validation enabled, e.g. js.AddConsumer with MaxRequestBatch: -5 or a computed batch limit that went negative.
Common situations: Arithmetic like defaultBatch - extra producing a negative number; config flags such as --max-request-batch=-1; tenants copying other 'unlimited = -1' conventions from fields like MaxAckPending where -1 is legal but here it is not.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- max_bytes must not be negative
- got corrupted escaped character
- max_ack_pending must be set to -1
- max_expires must not be negative
- idle_heartbeat must not be negative
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/a360577511a3100e.
Report an issue: GitHub.