nats-io/nats-server · error · JSPedanticError
max_consumers must be set to -1
Error message
max_consumers must be set to -1
What it means
Pedantic-mode validation for MaxConsumers (consumer count limit): 0 or any value < -1 triggers JSPedanticError; only -1 (unlimited) or a positive count passes. Non-pedantic mode silently sets it to -1.
Source
Thrown at server/stream.go:1946
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_msgs_per_subject must be set to -1"))
}
cfg.MaxMsgsPer = -1
}
if cfg.MaxBytes == 0 || cfg.MaxBytes < -1 {
if pedantic && cfg.MaxBytes < -1 {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_bytes must be set to -1"))
}
cfg.MaxBytes = -1
}
if cfg.MaxMsgSize == 0 || cfg.MaxMsgSize < -1 {
if pedantic && cfg.MaxMsgSize < -1 {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_msg_size must be set to -1"))
}
cfg.MaxMsgSize = -1
}
if cfg.MaxConsumers == 0 || cfg.MaxConsumers < -1 {
if pedantic && cfg.MaxConsumers < -1 {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_consumers must be set to -1"))
}
cfg.MaxConsumers = -1
}
if cfg.MaxAge < 0 {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("max age can not be negative"))
}
if cfg.MaxAge != 0 && cfg.MaxAge < 100*time.Millisecond {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("max age needs to be >= 100ms"))
}
if cfg.Duplicates == 0 && cfg.Mirror == nil && len(cfg.Sources) == 0 {
maxWindow := StreamDefaultDuplicatesWindow
if lim.Duplicates > 0 && maxWindow > lim.Duplicates {
if pedantic {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("duplicate window limits are higher than current limits"))
}
maxWindow = lim.Duplicates
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Set MaxConsumers to -1 for unlimited consumers
- Set a positive consumer quota (e.g. 100) if you want to cap consumers
- Disable pedantic checks to permit 0 -> -1 coercion
Example fix
// before
StreamConfig{Name: "ORDERS", MaxConsumers: 0}
// after
StreamConfig{Name: "ORDERS", MaxConsumers: -1} Defensive patterns
Strategy: validation
Validate before calling
if cfg.MaxConsumers == 0 || cfg.MaxConsumers < -1 {
return fmt.Errorf("MaxConsumers must be -1 (unlimited) or positive; got %d", cfg.MaxConsumers)
} Try / catch
if err != nil {
var apiErr *nats.APIError
if errors.As(err, &apiErr) && apiErr.ErrorCode == nats.ErrorCodeJetStreamInvalidStreamConfig {
cfg.MaxConsumers = -1
err = createStream(cfg)
}
} Prevention
- Set MaxConsumers explicitly in every stream template
- Normalize UI defaults to -1 rather than 0 for 'unlimited'
- Run pedantic-mode validation in CI to catch these early
When it happens
Trigger: Stream create/update in pedantic mode with MaxConsumers=0 or MaxConsumers<-1; e.g. a UI that defaults the field to 0 intending 'unlimited'. server/stream.go:1946.
Common situations: Streams expected to be attached to many consumers but config left unset; quota tools emitting 0; enabling pedantic mode after server upgrade on existing templates.
Related errors
- max_msgs must be set to -1
- max_msgs_per_subject must be set to -1
- max_bytes must be set to -1
- max_msg_size must be set to -1
- duplicate window cannot be bigger than max age
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/b82db1ddac1f2221.
Report an issue: GitHub.