nats-io/nats-server · error · JSStreamInvalidConfigError
stream description is too long, maximum allowed is %d
Error message
stream description is too long, maximum allowed is %d
What it means
checkStreamCfgLocked: the stream's human-readable Description exceeds JSMaxDescriptionLen bytes. Purely a config-size guard on the optional description field; the maximum allowed length is printed so the operator can truncate accordingly.
Source
Thrown at server/stream.go:1880
}
return s.checkStreamCfgLocked(config, acc, pedantic)
}
// jetStream lock (read or write) should be held, if JetStream is enabled.
func (s *Server) checkStreamCfgLocked(config *StreamConfig, acc *Account, pedantic bool) (StreamConfig, *ApiError) {
lim := &s.getOpts().JetStreamLimits
if config == nil {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream configuration invalid"))
}
if !isValidAssetName(config.Name) {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream name is required and can not contain '.', '*', '>', '\\', '/'"))
}
if len(config.Name) > JSMaxNameLen {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream name is too long, maximum allowed is %d", JSMaxNameLen))
}
if len(config.Description) > JSMaxDescriptionLen {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream description is too long, maximum allowed is %d", JSMaxDescriptionLen))
}
var metadataLen int
for k, v := range config.Metadata {
metadataLen += len(k) + len(v)
}
if metadataLen > JSMaxMetadataLen {
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream metadata exceeds maximum size of %d bytes", JSMaxMetadataLen))
}
cfg := *config
if _, err := cfg.Retention.MarshalJSON(); err != nil {
return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid retention"))
}
if _, err := cfg.Discard.MarshalJSON(); err != nil {
return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid discard policy"))
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Shorten the description to <=4096 bytes.
- Move large documentation to external storage and reference a URL in the description.
- Use Metadata for machine-readable key/value data with its own (larger) budget.
- Add a client-side length check before calling AddStream/Update.
Example fix
// before
cfg := jetstream.StreamConfig{Name: "ORDERS", Description: strings.Repeat("x", 5000)}
// after
desc := strings.Repeat("x", 5000)
cfg := jetstream.StreamConfig{Name: "ORDERS", Description: desc[:4000]} Defensive patterns
Strategy: validation
Validate before calling
func validDescription(d string) error {
if len(d) > 4096 {
return fmt.Errorf("description too long: %d > 4096", len(d))
}
return nil
} Type guard
func descFits(d string) bool { return len(d) <= 4096 } Prevention
- Truncate descriptions to a sane length at config load time.
- Don't embed documents, schemas, or dump output into Description.
- Use Metadata for structured data within its 128 KiB budget.
- Byte-count (len) descriptions containing non-ASCII text.
When it happens
Trigger: Creating or updating a stream with StreamConfig.Description longer than 4096 bytes, e.g. embedding documentation, JSON blobs, or auto-generated text into the description field.
Common situations: Storing schema definitions or owner/contact info in the description; scripts that dump a file's contents into the description; templates that interpolate large values.
Related errors
- JS_STREAM_MSG_DELETE_FAILED
- JS_STREAM_PURGE_FAILED
- JS_STREAM_ROLLUP_FAILED
- stream republish transform from '%s' to '%s': %w
- stream configuration invalid
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/4f81242ccaa9fcbc.
Report an issue: GitHub.