nats-io/nats-server · error · JSStreamInvalidConfigError
maximum replicas is %d
Error message
maximum replicas is %d
What it means
JetStream stream configuration validation rejects a stream whose Replicas count exceeds StreamMaxReplicas (the server's maximum supported R for mirrored/clustered streams). The server wraps it in a JSStreamInvalidConfigError during stream config normalization. This prevents creating or updating a stream with a replication factor the server cannot support.
Source
Thrown at server/stream.go:1915
return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid discard policy"))
}
if _, err := cfg.Compression.MarshalJSON(); err != nil {
return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid compression"))
}
// Make file the default.
if cfg.Storage == 0 {
cfg.Storage = FileStorage
}
if _, err := cfg.Storage.MarshalJSON(); err != nil {
return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid storage type"))
}
if cfg.Replicas == 0 {
cfg.Replicas = 1
}
if cfg.Replicas > StreamMaxReplicas {
return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("maximum replicas is %d", StreamMaxReplicas))
}
if cfg.Replicas < 0 {
return cfg, NewJSReplicasCountCannotBeNegativeError()
}
if cfg.MaxMsgs == 0 || cfg.MaxMsgs < -1 {
if pedantic && cfg.MaxMsgs < -1 {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_msgs must be set to -1"))
}
cfg.MaxMsgs = -1
}
if cfg.MaxMsgsPer == 0 || cfg.MaxMsgsPer < -1 {
if pedantic && cfg.MaxMsgsPer < -1 {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("max_msgs_per_subject must be set to -1"))
}
cfg.MaxMsgsPer = -1
}
if cfg.MaxBytes == 0 || cfg.MaxBytes < -1 {
if pedantic && cfg.MaxBytes < -1 {View on GitHub (pinned to 3a66a489d2)
Solutions
- Lower the stream's Replicas in the StreamConfig to a value <= StreamMaxReplicas (check the constant in your server version)
- If you need higher replication, upgrade the nats-server to a version with a higher StreamMaxReplicas
- If clusters/servers are the real intent, use raft placement/placement tags rather than inflating replicas
Example fix
// before
cfg := jetstream.StreamConfig{Name: "ORDERS", Replicas: 10}
// after
cfg := jetstream.StreamConfig{Name: "ORDERS", Replicas: 3} Defensive patterns
Strategy: validation
Validate before calling
if cfg.Replicas < 0 || cfg.Replicas > jetstream.MaxReplicasCap { // check your server's StreamMaxReplicas
return fmt.Errorf("replicas %d exceeds server maximum", cfg.Replicas)
} Try / catch
err := createStream(cfg)
var apiErr *nats.APIError
if errors.As(err, &apiErr) && apiErr.ErrorCode == nats.ErrorCodeJetStreamInvalidStreamConfig {
// surface a config-fix hint to the user
} Prevention
- Cap Replicas in your config templates to the lowest supported maximum
- Read the constant from the server version you deploy against, not from client defaults
- Validate stream configs in CI before applying to production
When it happens
Trigger: Calling stream create/update API (JS API $JS.API.STREAM.CREATE/UPDATE) with config.replicas set higher than StreamMaxReplicas; e.g. submitting replicas=10 when the server max is lower. Occurs in the server-side config check (server/stream.go:1915) before the stream is persisted.
Common situations: Copy-pasted config from another deployment (e.g. cloud with higher replica cap); misreading replicas as 'number of servers'; accidental multiplication in config templating; upgrading clients that allow higher R than this server version supports.
Related errors
- JS_ERR_GENERIC
- stream republish transform from '%s' to '%s': %w
- max_msgs must be set to -1
- max_msgs_per_subject must be set to -1
- max_bytes must be set to -1
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/8c3976499441d8bd.
Report an issue: GitHub.