{"record":{"id":"827b5665c9b81176","repo":"nats-io/nats-server","slug":"consumer-durable-name-can-not-contain","errorCode":null,"errorMessage":"consumer durable name can not contain '.', '*', '>', '\\', '/'","messagePattern":"consumer durable name can not contain '\\.', '\\*', '>', '\\\\', '/'","errorType":"validation","errorClass":"ApiError","httpStatus":null,"severity":"error","filePath":"server/consumer.go","lineNumber":742,"sourceCode":"\t}\n\treturn nil\n}\n\n// Check the consumer config. If we are recovering don't check filter subjects.\nfunc checkConsumerCfg(\n\tconfig *ConsumerConfig,\n\tsrvLim *JSLimitOpts,\n\tcfg *StreamConfig,\n\t_ *Account,\n\taccLim *JetStreamAccountLimits,\n\tisRecovering bool,\n) *ApiError {\n\n\tif config.Name != _EMPTY_ && !isValidAssetName(config.Name) {\n\t\treturn NewJSStreamInvalidConfigError(errors.New(\"consumer name can not contain '.', '*', '>', '\\\\', '/'\"))\n\t}\n\tif config.Durable != _EMPTY_ && !isValidAssetName(config.Durable) {\n\t\treturn NewJSStreamInvalidConfigError(errors.New(\"consumer durable name can not contain '.', '*', '>', '\\\\', '/'\"))\n\t}\n\n\t// Check if replicas is defined but exceeds parent stream.\n\tif config.Replicas > 0 && config.Replicas > cfg.Replicas {\n\t\treturn NewJSConsumerReplicasExceedsStreamError()\n\t}\n\t// Check that it is not negative\n\tif config.Replicas < 0 {\n\t\treturn NewJSReplicasCountCannotBeNegativeError()\n\t}\n\t// If the stream is interest or workqueue retention make sure the replicas\n\t// match that of the stream. This is REQUIRED for now.\n\tif cfg.Retention == InterestPolicy || cfg.Retention == WorkQueuePolicy {\n\t\t// Only error here if not recovering.\n\t\t// We handle recovering in a different spot to allow consumer to come up\n\t\t// if previous version allowed it to be created. We do not want it to not come up.\n\t\tif !isRecovering && config.Replicas != 0 && config.Replicas != cfg.Replicas {\n\t\t\treturn NewJSConsumerReplicasShouldMatchStreamError()","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/consumer.go#L724-L760","documentation":"The consumer's Durable field failed isValidAssetName because it contains '.', '*', '>', '\\\\' or '/'. Durable names become part of internal subjects and storage keys, so wildcard/path characters are forbidden. The server rejects the request with a JSStreamInvalidConfigError.","triggerScenarios":"Any consumer create/update call where config.Durable is non-empty and contains one of the forbidden characters: '.', '*', '>', '\\\\' or '/'.","commonSituations":"Using domain-like durable names such as 'my.app.worker'; reusing subscription subject strings as durable names; copy-pasting names from configs with slashes; clients from other ecosystems (e.g. Kafka group ids with dots) carried over.","solutions":["Replace forbidden characters in the durable name with '-', '_' or alphanumerics.","Add a sanitize/validate step before constructing ConsumerConfig.","Let the server generate the durable name by omitting Durable when ephemeral behavior is acceptable.","Keep durable names in one canonical format across services to avoid recurring validation failures."],"exampleFix":"// before\ncc := &nats.ConsumerConfig{Durable: \"billing.worker.v2\"}\n// after\ncc := &nats.ConsumerConfig{Durable: \"billing-worker-v2\"}","handlingStrategy":"validation","validationCode":"var invalidAssetNameRe = regexp.MustCompile(`[.*>\\\\/]`)\nfunc validDurableName(durable string) bool {\n\treturn durable == \"\" || !invalidAssetNameRe.MatchString(durable)\n}\nif !validDurableName(cc.Durable) {\n\treturn fmt.Errorf(\"invalid durable name %q\", cc.Durable)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize durable naming (alphanumerics, '-', '_') across services","Validate durable names in CI config generation","Do not reuse Kafka-style group IDs containing dots without sanitizing"],"tags":["jetstream","consumer","durable","naming","config-validation"],"backgroundTag":"invalid-asset-name","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}