{"record":{"id":"55f16c3f36b5e590","repo":"nats-io/nats-server","slug":"config-reload-not-supported-for-jetstream-dynamic","errorCode":null,"errorMessage":"config reload not supported for jetstream dynamic max memory and store","messagePattern":"config reload not supported for jetstream dynamic max memory and store","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/reload.go","lineNumber":1860,"sourceCode":"\t\t\t\t\t\tjsLimitsUpdate = &jetStreamLimitsOption{}\n\t\t\t\t\t\tdiffOpts = append(diffOpts, jsLimitsUpdate)\n\t\t\t\t\t}\n\t\t\t\t\tif optName == \"jetstreammaxmemory\" {\n\t\t\t\t\t\tjsLimitsUpdate.newMaxMemory = new\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjsLimitsUpdate.newMaxStore = new\n\t\t\t\t\t}\n\t\t\t\tcase fromSet && toUnset:\n\t\t\t\t\t// Limits changed but it may mean that JS is being disabled,\n\t\t\t\t\t// keep track of the change and error in case it is not.\n\t\t\t\t\tif optName == \"jetstreammaxmemory\" {\n\t\t\t\t\t\tjsMemLimitsChanged = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjsFileLimitsChanged = true\n\t\t\t\t\t}\n\t\t\t\tcase fromUnset && toSet:\n\t\t\t\t\t// Prevent changing from dynamic max memory / file at runtime.\n\t\t\t\t\treturn nil, fmt.Errorf(\"config reload not supported for jetstream dynamic max memory and store\")\n\t\t\t\tdefault:\n\t\t\t\t\treturn nil, fmt.Errorf(\"config reload not supported for decreasing jetstream max memory and store\")\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"jetstreammetacompact\", \"jetstreammetacompactsize\", \"jetstreammetacompactsync\":\n\t\t\t// Allowed at runtime but monitorCluster looks at s.opts directly, so no further work needed here.\n\t\tcase \"jetstreamconcurrentios\":\n\t\t\t// Not reloadable at runtime; preserve the current value while JetStream is disabled,\n\t\t\t// e.g. the entire jetstream{} block was deleted.\n\t\t\tif newOpts.JetStream {\n\t\t\t\treturn nil, fmt.Errorf(\"config reload not supported for %s: old=%v, new=%v\",\n\t\t\t\t\tfield.Name, oldValue, newValue)\n\t\t\t} else {\n\t\t\t\tnewOpts.JetStreamConcurrentIOs = oldValue.(int)\n\t\t\t}\n\t\tcase \"websocket\":\n\t\t\t// Similar to gateways\n\t\t\ttmpOld := oldValue.(WebsocketOpts)","sourceCodeStart":1842,"sourceCodeEnd":1878,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/reload.go#L1842-L1878","documentation":"When `jetstream.max_memory` or `jetstream.max_store` is unset (-1 / absent) in the old config, JetStream uses dynamic limits. The reload path forbids transitions from unset to explicitly set limits at runtime, because the dynamic account limit propagation cannot be safely re-derived mid-flight. The reload is rejected with this error.","triggerScenarios":"Signaling reload after changing `jetstream.max_memory` or `jetstream.max_store` from absent/-1 to a concrete byte value (e.g. 1GB) while JetStream is enabled.","commonSituations":"Operators first running without limits then deciding to cap usage and attempting to apply it via reload; config automation that adds explicit limits to a config that previously omitted them; aligning configs across a cluster where some nodes had limits and others didn't.","solutions":["Restart the server to apply explicit max_memory/max_store for the first time","Keep limits unset (-1) if reload continuity is required and manage caps at the account level where possible","Change existing explicit limits (set→set) which may be allowed if not decreasing — avoid unset→set transitions"],"exampleFix":"// before\njetstream { max_memory: 1GB }  # was unset, + reload signal\n// after\nserver # systemctl restart nats-server  (first-time explicit limits need restart)","handlingStrategy":"validation","validationCode":"// Block unset→set limit transitions before reload:\nfunc dynamicToStaticLimits(old, new *Options) bool {\n\tconst unset = int64(-1)\n\tif old.JetStream && new.JetStream {\n\t\tif (old.MaxMemory == unset || old.MaxMemoryMax == unset) && new.MaxMemory > 0 { return true }\n\t\tif (old.MaxStore == unset || old.MaxStoreMax == unset) && new.MaxStore > 0 { return true }\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Decide memory/store limits at initial deployment; keep them explicit thereafter","Avoid copying configs between nodes with mixed unset/set limits","Use restarts to introduce limits for the first time"],"tags":["nats-server","config-reload","jetstream"],"backgroundTag":"jetstream-limit-reload-unsupported","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}