{"record":{"id":"05b1b24d2c76643b","repo":"nats-io/nats-server","slug":"max-bytes-must-be-set-to-1","errorCode":null,"errorMessage":"max_bytes must be set to -1","messagePattern":"max_bytes must be set to -1","errorType":"error_code","errorClass":"JSPedanticError","httpStatus":null,"severity":"error","filePath":"server/stream.go","lineNumber":1934,"sourceCode":"\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\"))\n\t\t}\n\t\tcfg.MaxMsgSize = -1\n\t}\n\tif cfg.MaxConsumers == 0 || cfg.MaxConsumers < -1 {\n\t\tif pedantic && cfg.MaxConsumers < -1 {\n\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"max_consumers must be set to -1\"))\n\t\t}\n\t\tcfg.MaxConsumers = -1\n\t}\n\tif cfg.MaxAge < 0 {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"max age can not be negative\"))\n\t}","sourceCodeStart":1916,"sourceCodeEnd":1952,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L1916-L1952","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nStreamConfig{Name: \"ORDERS\", MaxBytes: 0}\n// after\nStreamConfig{Name: \"ORDERS\", MaxBytes: 1073741824}","handlingStrategy":"validation","validationCode":"if cfg.MaxBytes == 0 || cfg.MaxBytes < -1 {\n    return fmt.Errorf(\"MaxBytes must be -1 (unlimited) or positive; got %d\", cfg.MaxBytes)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var apiErr *nats.APIError\n    if errors.As(err, &apiErr) && apiErr.ErrorCode == nats.ErrorCodeJetStreamInvalidStreamConfig {\n        cfg.MaxBytes = -1\n        err = createStream(cfg)\n    }\n}","preventionTips":["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"],"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-08T10:18:20.063Z"}