nats-io/nats-server · error · JSPedanticError
max_bytes must be set to -1
Error message
max_bytes must be set to -1
What it means
checkStreamCfgLocked (pedantic mode): MaxBytes was set below -1 (not 0 or -1). Non-pedantic mode silently coerces it to -1 (unlimited); pedantic mode rejects the config and demands the canonical -1 sentinel. Applies to max_bytes in the stream config.
Source
Thrown at server/stream.go:1934
}
if cfg.Replicas < 0 {
return cfg, NewJSReplicasCountCannotBeNegativeError()
}
if cfg.MaxMsgs == 0 || cfg.MaxMsgs < -1 {
if pedantic && cfg.MaxMsgs < -1 {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_msgs must be set to -1"))
}
cfg.MaxMsgs = -1
}
if cfg.MaxMsgsPer == 0 || cfg.MaxMsgsPer < -1 {
if pedantic && cfg.MaxMsgsPer < -1 {
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"))
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Set MaxBytes to -1 explicitly for unlimited storage
- Set a positive byte limit for the stream's max size
- Disable pedantic mode if you rely on implicit 0 -> unlimited normalization
Example fix
// before
StreamConfig{Name: "ORDERS", MaxBytes: 0}
// after
StreamConfig{Name: "ORDERS", MaxBytes: 1073741824} Defensive patterns
Strategy: validation
Validate before calling
if cfg.MaxBytes == 0 || cfg.MaxBytes < -1 {
return fmt.Errorf("MaxBytes must be -1 (unlimited) or positive; got %d", cfg.MaxBytes)
} Try / catch
if err != nil {
var apiErr *nats.APIError
if errors.As(err, &apiErr) && apiErr.ErrorCode == nats.ErrorCodeJetStreamInvalidStreamConfig {
cfg.MaxBytes = -1
err = createStream(cfg)
}
} Prevention
- Clamp computed byte budgets to >= 0 before assigning
- Use explicit constants (e.g. NoLimit = -1) instead of raw 0/negatives
- Validate quotas from external systems before mapping them to MaxBytes
When it happens
Trigger: Stream create/update in pedantic mode with MaxBytes=0 or MaxBytes<-1; e.g. a quota calculator that produced a negative byte budget. server/stream.go:1934.
Common situations: Byte-based retention configs left at zero expecting 'no limit'; arithmetic bugs (limit computed as size-used going negative); enabling pedantic checks on legacy configs.
Related errors
- max_msgs must be set to -1
- max_msgs_per_subject must be set to -1
- max_msg_size must be set to -1
- max_consumers 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/05b1b24d2c76643b.
Report an issue: GitHub.