nats-io/nats-server · error · JSStreamInvalidConfigError
duplicates window can not be larger then server limit of %v
Error message
duplicates window can not be larger then server limit of %v
What it means
If the server (or account/template limits) defines a maximum Duplicates window (lim.Duplicates > 0), validation rejects any configured window larger than that server-side limit. This keeps duplicate-detection caches from growing beyond operational limits imposed via server config, account limits, or stream templates. Returned as a JSStreamInvalidConfigError including the limit value in the message.
Source
Thrown at server/stream.go:1982
}
if cfg.MaxAge != 0 && cfg.MaxAge < maxWindow {
if pedantic {
return StreamConfig{}, NewJSPedanticError(fmt.Errorf("duplicate window cannot be bigger than max age"))
}
cfg.Duplicates = cfg.MaxAge
} else {
cfg.Duplicates = maxWindow
}
}
if cfg.Duplicates < 0 {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("duplicates window can not be negative"))
}
// Check that duplicates is not larger then age if set.
if cfg.MaxAge != 0 && cfg.Duplicates > cfg.MaxAge {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("duplicates window can not be larger then max age"))
}
if lim.Duplicates > 0 && cfg.Duplicates > lim.Duplicates {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("duplicates window can not be larger then server limit of %v",
lim.Duplicates.String()))
}
if cfg.Duplicates > 0 && cfg.Duplicates < 100*time.Millisecond {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("duplicates window needs to be >= 100ms"))
}
if cfg.DenyPurge && cfg.AllowRollup {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("roll-ups require the purge permission"))
}
// Counter is not compatible with some settings.
if cfg.AllowMsgCounter {
if cfg.Discard == DiscardNew {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("counter stream cannot use discard new"))
}
if cfg.AllowMsgTTL {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("counter stream cannot use message TTLs"))
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Read the effective limits (AccountInfo / JetStream limits) and clamp Duplicates to the reported limit.
- Lower StreamConfig.Duplicates to at or below the server limit shown in the error message.
- Ask the operator to raise the duplicates limit in the account limits if a longer window is genuinely needed.
- Make Duplicates configurable per environment rather than hardcoded.
Example fix
// before
StreamConfig{Name: "ORDERS", Duplicates: 10 * time.Minute} // account limit: 2m
// after
StreamConfig{Name: "ORDERS", Duplicates: 2 * time.Minute} Defensive patterns
Strategy: validation
Validate before calling
info, err := js.AccountInfo(ctx)
if err != nil {
return err
}
if max := info.Limits.StreamLimits.Duplicates; max > 0 && cfg.Duplicates > max {
cfg.Duplicates = max
} Try / catch
var scErr *jetstream.JSApiError
if _, err := js.CreateStream(ctx, cfg); errors.As(err, &scErr) && strings.Contains(scErr.Description, "duplicates window can not be larger then server limit") {
return fmt.Errorf("reduce Duplicates to the account limit: %w", err)
} Prevention
- Call AccountInfo at startup and clamp Duplicates to StreamLimits.Duplicates.
- Make Duplicates configurable per environment instead of hardcoding.
- Document account limits when deploying to multi-tenant clusters.
When it happens
Trigger: AddStream/UpdateStream with StreamConfig.Duplicates exceeding the duplicates limit from JetStreamAccountLimits or StreamLimits (e.g. requesting 10m when the account caps duplicates at 2m).
Common situations: Shared/multi-tenant NATS deployments where operators cap duplicate windows per account; deploying an app with a hardcoded large Duplicates value into a cluster with tighter limits than the dev environment.
Related errors
- duplicates window can not be negative
- duplicates window can not be larger then max age
- duplicates window needs to be >= 100ms
- roll-ups require the purge permission
- counter stream cannot use discard new
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/5bb2c838d81e6226.
Report an issue: GitHub.