{"record":{"id":"a072511656ba2758","repo":"nats-io/nats-server","slug":"max-msg-size-must-be-set-to-1","errorCode":null,"errorMessage":"max_msg_size must be set to -1","messagePattern":"max_msg_size must be set to -1","errorType":"error_code","errorClass":"JSPedanticError","httpStatus":null,"severity":"error","filePath":"server/stream.go","lineNumber":1940,"sourceCode":"\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}\n\tif cfg.MaxAge != 0 && cfg.MaxAge < 100*time.Millisecond {\n\t\treturn StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf(\"max age needs to be >= 100ms\"))\n\t}\n\n\tif cfg.Duplicates == 0 && cfg.Mirror == nil && len(cfg.Sources) == 0 {\n\t\tmaxWindow := StreamDefaultDuplicatesWindow","sourceCodeStart":1922,"sourceCodeEnd":1958,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L1922-L1958","documentation":"checkStreamCfgLocked (pedantic mode): MaxMsgSize was set below -1 (not 0 or -1). Non-pedantic mode coerces it to -1 (unlimited); pedantic mode refuses the config, requiring the explicit -1 sentinel for unlimited max_msg_size.","triggerScenarios":"Stream create/update API in pedantic mode with MaxMsgSize=0 or a negative value other than -1; e.g. pulling the limit from an environment variable that defaulted to 0 or -2. server/stream.go:1940.","commonSituations":"Max message size inherited from NATS core's max_payload logic but left unset; env-var parsing failures yielding 0; strict validation turned on in clustered deployments.","solutions":["Set MaxMsgSize explicitly to -1 for no per-message size limit","Set MaxMsgSize to a positive byte value (e.g. 1048576) matching your payload budget","Run without pedantic validation to allow silent normalization"],"exampleFix":"// before\nStreamConfig{Name: \"ORDERS\", MaxMsgSize: 0}\n// after\nStreamConfig{Name: \"ORDERS\", MaxMsgSize: 2097152}","handlingStrategy":"validation","validationCode":"if cfg.MaxMsgSize == 0 || cfg.MaxMsgSize < -1 {\n    return fmt.Errorf(\"MaxMsgSize must be -1 (unlimited) or positive; got %d\", cfg.MaxMsgSize)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var apiErr *nats.APIError\n    if errors.As(err, &apiErr) && apiErr.ErrorCode == nats.ErrorCodeJetStreamInvalidStreamConfig {\n        cfg.MaxMsgSize = -1\n        err = createStream(cfg)\n    }\n}","preventionTips":["Default MaxMsgSize to the server's max_payload if unlimited is intended","Validate env-var parsing so missing values do not become 0","Document the -1 sentinel in your config schema"],"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"}