{"record":{"id":"1f7fc3487a4d3048","repo":"nats-io/nats-server","slug":"max-msgs-must-be-set-to-1","errorCode":null,"errorMessage":"max_msgs must be set to -1","messagePattern":"max_msgs must be set to -1","errorType":"error_code","errorClass":"JSPedanticError","httpStatus":null,"severity":"error","filePath":"server/stream.go","lineNumber":1922,"sourceCode":"\tif cfg.Storage == 0 {\n\t\tcfg.Storage = FileStorage\n\t}\n\tif _, err := cfg.Storage.MarshalJSON(); err != nil {\n\t\treturn cfg, NewJSStreamInvalidConfigError(fmt.Errorf(\"invalid storage type\"))\n\t}\n\n\tif cfg.Replicas == 0 {\n\t\tcfg.Replicas = 1\n\t}\n\tif cfg.Replicas > StreamMaxReplicas {\n\t\treturn cfg, NewJSStreamInvalidConfigError(fmt.Errorf(\"maximum replicas is %d\", StreamMaxReplicas))\n\t}\n\tif cfg.Replicas < 0 {\n\t\treturn cfg, NewJSReplicasCountCannotBeNegativeError()\n\t}\n\tif cfg.MaxMsgs == 0 || cfg.MaxMsgs < -1 {\n\t\tif pedantic && cfg.MaxMsgs < -1 {\n\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"max_msgs must be set to -1\"))\n\t\t}\n\t\tcfg.MaxMsgs = -1\n\t}\n\tif cfg.MaxMsgsPer == 0 || cfg.MaxMsgsPer < -1 {\n\t\tif pedantic && cfg.MaxMsgsPer < -1 {\n\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"max_msgs_per_subject must be set to -1\"))\n\t\t}\n\t\tcfg.MaxMsgsPer = -1\n\t}\n\tif cfg.MaxBytes == 0 || cfg.MaxBytes < -1 {\n\t\tif pedantic && cfg.MaxBytes < -1 {\n\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"max_bytes must be set to -1\"))\n\t\t}\n\t\tcfg.MaxBytes = -1\n\t}\n\tif cfg.MaxMsgSize == 0 || cfg.MaxMsgSize < -1 {\n\t\tif pedantic && cfg.MaxMsgSize < -1 {\n\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"max_msg_size must be set to -1\"))","sourceCodeStart":1904,"sourceCodeEnd":1940,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L1904-L1940","documentation":"In pedantic mode, the server refuses to silently coerce an unset or invalid MaxMsgs value: 0 or any value < -1 triggers a JSPedanticError unless it is exactly -1 (unlimited). Non-pedantic mode would silently set MaxMsgs=-1. This enforces explicit configuration instead of implicit defaults.","triggerScenarios":"Creating/updating a stream with MaxMsgs=0 or MaxMsgs<-1 (e.g. -5) while the request runs in pedantic mode (server option or client that requests strict config validation). server/stream.go:1922.","commonSituations":"Configs built programmatically leaving MaxMsgs at zero and expecting 'unlimited'; UI/templating producing negative sentinel values other than -1; enabling pedantic mode (e.g. for compliance) on configs that previously relied on silent normalization.","solutions":["Set MaxMsgs explicitly to -1 for unlimited retention","Set MaxMsgs to a positive count matching your retention policy","Remove MaxMsgs entirely only if not using pedantic mode, or run without pedantic checks"],"exampleFix":"// before\nStreamConfig{Name: \"ORDERS\", MaxMsgs: 0}\n// after\nStreamConfig{Name: \"ORDERS\", MaxMsgs: -1}","handlingStrategy":"validation","validationCode":"if cfg.MaxMsgs == 0 || cfg.MaxMsgs < -1 {\n    return fmt.Errorf(\"MaxMsgs must be -1 (unlimited) or positive; got %d\", cfg.MaxMsgs)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var apiErr *nats.APIError\n    if errors.As(err, &apiErr) && apiErr.ErrorCode == nats.ErrorCodeJetStreamInvalidStreamConfig {\n        cfg.MaxMsgs = -1\n        err = createStream(cfg)\n    }\n}","preventionTips":["Always initialize retention fields explicitly; never rely on zero-values with pedantic mode","Use -1 as the single 'unlimited' sentinel across your configs","Test stream creation with pedantic validation enabled in staging"],"tags":["jetstream","stream-config","pedantic","validation"],"backgroundTag":"jetstream-invalid-stream-config","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}