{"record":{"id":"047b16c82f98620a","repo":"nats-io/nats-server","slug":"jetstream-max-catchup-cannot-be-negative","errorCode":null,"errorMessage":"jetstream max catchup cannot be negative","messagePattern":"jetstream max catchup cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jetstream.go","lineNumber":2956,"sourceCode":"\t\treturn nil\n\t}\n\tif o.ServerName == _EMPTY_ {\n\t\treturn fmt.Errorf(\"jetstream cluster requires `server_name` to be set\")\n\t}\n\tif o.Cluster.Name == _EMPTY_ {\n\t\treturn fmt.Errorf(\"jetstream cluster requires `cluster.name` to be set\")\n\t}\n\n\th := strings.ToLower(o.JetStreamExtHint)\n\tswitch h {\n\tcase jsWillExtend, jsNoExtend, _EMPTY_:\n\t\to.JetStreamExtHint = h\n\tdefault:\n\t\treturn fmt.Errorf(\"expected 'no_extend' for string value, got '%s'\", h)\n\t}\n\n\tif o.JetStreamMaxCatchup < 0 {\n\t\treturn fmt.Errorf(\"jetstream max catchup cannot be negative\")\n\t}\n\treturn nil\n}\n\n// We had a bug that set a default de dupe window on mirror, despite that being not a valid config\nfunc fixCfgMirrorWithDedupWindow(cfg *StreamConfig) {\n\tif cfg == nil || cfg.Mirror == nil {\n\t\treturn\n\t}\n\tif cfg.Duplicates != 0 {\n\t\tcfg.Duplicates = 0\n\t}\n}\n\nfunc (s *Server) handleWritePermissionError() {\n\t//TODO Check if we should add s.jetStreamOOSPending in condition\n\tif s.JetStreamEnabled() {\n\t\ts.Errorf(\"File system permission denied while writing, disabling JetStream\")","sourceCodeStart":2938,"sourceCodeEnd":2974,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream.go#L2938-L2974","documentation":"JetStream options validation: the configured JetStreamMaxCatchup value is negative, which is meaningless for a byte limit; only zero (default) or positive values are accepted.","triggerScenarios":"Configuring a negative value for the jetstream max catchup limit (e.g. `max_catchup: -1`) in the server config.","commonSituations":"Operator intending 'unlimited' and guessing -1; arithmetic or templating bugs generating negative numbers into the config.","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."],"exampleFix":"// before\njetstream: { max_catchup: -1 }\n// after\njetstream: { max_catchup: 0 }","handlingStrategy":"validation","validationCode":"if cfg.JetStream.MaxCatchup < 0 {\n    return errors.New(\"jetstream max catchup cannot be negative\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use 0 to mean 'no explicit limit', not -1.","Clamp generated values to >= 0 before writing config.","Guard any arithmetic that feeds this option."],"tags":["jetstream","configuration","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}