nats-io/nats-server · error · JSStreamInvalidConfigError
stream name is too long, maximum allowed is %d
Error message
stream name is too long, maximum allowed is %d
What it means
checkStreamCfgLocked: the stream's Name/identifier field exceeds the server's maximum asset-name length (JSMaxNameLen). Streams, consumers and other JetStream assets share a length cap because names are embedded in subjects and file paths; a longer name is rejected with the allowed maximum printed.
Source
Thrown at server/stream.go:1877
if js := s.getJetStream(); js != nil {
js.mu.RLock()
defer js.mu.RUnlock()
}
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"))
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Shorten the stream name to <=255 bytes.
- Truncate or hash long identifiers (e.g. sha256 hex) before using them as stream names.
- Add a client-side check len(name) <= 255 before sending the create request.
- Move extra identifying data into StreamConfig.Description or Metadata instead of the name.
Example fix
// before
name := tenant + "-" + longUUID + "-" + timestamp // > 255 chars
js.CreateStream(ctx, jetstream.StreamConfig{Name: name})
// after
name := tenant + "-" + hashHex(longUUID)[:16]
js.CreateStream(ctx, jetstream.StreamConfig{Name: name, Description: longUUID}) Defensive patterns
Strategy: validation
Validate before calling
func validStreamNameLen(name string) error {
if len(name) > 255 {
return fmt.Errorf("stream name too long: %d > 255", len(name))
}
return nil
} Type guard
func nameFits(name string) bool { return len(name) <= 255 } Prevention
- Check len(name) <= 255 before every create/update.
- Hash long identifiers instead of embedding them in names.
- Keep descriptive data in Description/Metadata, not the name.
- Beware multi-byte UTF-8: len() counts bytes, matching the server's rule.
When it happens
Trigger: Creating a stream whose Name is longer than 255 bytes; programmatically generated names (uuid + prefixes + timestamps) exceeding 255; user-supplied names without client-side length checks.
Common situations: Concatenating tenant prefixes and IDs into the stream name; hashing libraries producing long base64 names; application passing a description into the name field by mistake.
Related errors
- stream name is required and can not contain '.', '*', '>', '
- got corrupted escaped character
- incomplete type, value pair
- DN ended with incomplete type, value pair
- errors.New(strings.Join(errs, "\n"))
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/818e9d6303e61964.
Report an issue: GitHub.