nats-io/nats-server · error
jetstream max catchup cannot be negative
Error message
jetstream max catchup cannot be negative
What it means
JetStream options validation: the configured JetStreamMaxCatchup value is negative, which is meaningless for a byte limit; only zero (default) or positive values are accepted.
Source
Thrown at server/jetstream.go:2956
return nil
}
if o.ServerName == _EMPTY_ {
return fmt.Errorf("jetstream cluster requires `server_name` to be set")
}
if o.Cluster.Name == _EMPTY_ {
return fmt.Errorf("jetstream cluster requires `cluster.name` to be set")
}
h := strings.ToLower(o.JetStreamExtHint)
switch h {
case jsWillExtend, jsNoExtend, _EMPTY_:
o.JetStreamExtHint = h
default:
return fmt.Errorf("expected 'no_extend' for string value, got '%s'", h)
}
if o.JetStreamMaxCatchup < 0 {
return fmt.Errorf("jetstream max catchup cannot be negative")
}
return nil
}
// We had a bug that set a default de dupe window on mirror, despite that being not a valid config
func fixCfgMirrorWithDedupWindow(cfg *StreamConfig) {
if cfg == nil || cfg.Mirror == nil {
return
}
if cfg.Duplicates != 0 {
cfg.Duplicates = 0
}
}
func (s *Server) handleWritePermissionError() {
//TODO Check if we should add s.jetStreamOOSPending in condition
if s.JetStreamEnabled() {
s.Errorf("File system permission denied while writing, disabling JetStream")View on GitHub (pinned to 3a66a489d2)
Solutions
- Set the value to 0 or a positive integer (0 typically means no explicit limit).
- Remove the option to rely on the default behavior.
- Restart the server.
Example fix
// before
jetstream: { max_catchup: -1 }
// after
jetstream: { max_catchup: 0 } Defensive patterns
Strategy: validation
Validate before calling
if cfg.JetStream.MaxCatchup < 0 {
return errors.New("jetstream max catchup cannot be negative")
} Prevention
- Use 0 to mean 'no explicit limit', not -1.
- Clamp generated values to >= 0 before writing config.
- Guard any arithmetic that feeds this option.
When it happens
Trigger: Configuring a negative value for the jetstream max catchup limit (e.g. `max_catchup: -1`) in the server config.
Common situations: Operator intending 'unlimited' and guessing -1; arithmetic or templating bugs generating negative numbers into the config.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- got corrupted escaped character
- incomplete type, value pair
- DN ended with incomplete type, value pair
- errors.New(strings.Join(errs, "\n"))
- expected 'cert_store' to be a valid non-empty string
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/047b16c82f98620a.
Report an issue: GitHub.