nats-io/nats-server · error · ApiError
consumer name can not contain '.', '*', '>', '\', '/'
Error message
consumer name can not contain '.', '*', '>', '\', '/'
What it means
The consumer's Name field failed isValidAssetName, meaning it contains one of the forbidden characters '.', '*', '>', '\\' or '/'. JetStream asset names are used directly as NATS subjects/tokens, so these wildcard and path characters are rejected. The server returns this wrapped in a JSStreamInvalidConfigError during consumer config validation.
Source
Thrown at server/consumer.go:739
if config.AckPolicy == AckFlowControl && !pedantic {
config.FlowControl = true
config.Heartbeat = sourceHealthHB
}
return nil
}
// Check the consumer config. If we are recovering don't check filter subjects.
func checkConsumerCfg(
config *ConsumerConfig,
srvLim *JSLimitOpts,
cfg *StreamConfig,
_ *Account,
accLim *JetStreamAccountLimits,
isRecovering bool,
) *ApiError {
if config.Name != _EMPTY_ && !isValidAssetName(config.Name) {
return NewJSStreamInvalidConfigError(errors.New("consumer name can not contain '.', '*', '>', '\\', '/'"))
}
if config.Durable != _EMPTY_ && !isValidAssetName(config.Durable) {
return NewJSStreamInvalidConfigError(errors.New("consumer durable name can not contain '.', '*', '>', '\\', '/'"))
}
// Check if replicas is defined but exceeds parent stream.
if config.Replicas > 0 && config.Replicas > cfg.Replicas {
return NewJSConsumerReplicasExceedsStreamError()
}
// Check that it is not negative
if config.Replicas < 0 {
return NewJSReplicasCountCannotBeNegativeError()
}
// If the stream is interest or workqueue retention make sure the replicas
// match that of the stream. This is REQUIRED for now.
if cfg.Retention == InterestPolicy || cfg.Retention == WorkQueuePolicy {
// Only error here if not recovering.
// We handle recovering in a different spot to allow consumer to come upView on GitHub (pinned to 3a66a489d2)
Solutions
- Sanitize the consumer name, replacing '.', '*', '>', '\\' and '/' with allowed characters such as '-' or '_'.
- Generate a name programmatically (e.g. hash or slug) when the source string may contain reserved characters.
- Validate names client-side before calling the API.
- If a dotted name is required, leave Name empty and set only Durable (also subject to the same rule) or let the server assign one.
Example fix
// before
cc := &nats.ConsumerConfig{Name: "orders/eu.consumer"}
// after
cc := &nats.ConsumerConfig{Name: "orders-eu-consumer"} Defensive patterns
Strategy: validation
Validate before calling
var invalidAssetNameRe = regexp.MustCompile(`[.*>\\/]`)
func validConsumerName(name string) bool {
return name == "" || !invalidAssetNameRe.MatchString(name)
}
if !validConsumerName(cc.Name) {
return fmt.Errorf("invalid consumer name %q", cc.Name)
} Prevention
- Sanitize any user- or domain-derived strings before using them as consumer names
- Never pass NATS subjects or URLs directly as consumer names
- Add a shared name-slug helper used by all services creating consumers
When it happens
Trigger: Any consumer create/update API call (js.AddConsumer, $JS.API.CONSUMER.CREATE.<stream>.<name>) where config.Name is non-empty and contains '.', '*', '>', '\\' or '/'.
Common situations: Deriving consumer names from user input, file paths, or topic names containing dots/slashes; building names like 'app.consumer.v1' with slashes from URLs; accidentally passing a subject instead of a name.
Related errors
- consumer durable name can not contain '.', '*', '>', '\', '/
- max_request_batch must be set if it's JetStream limits are s
- 10094
- deliver policy can not be updated
- storage type can not be updated
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/96f6286114bce6f2.
Report an issue: GitHub.