{"record":{"id":"4ef618ed40a349b9","repo":"nats-io/nats-server","slug":"preferred-server-not-permitted-in-placement","errorCode":null,"errorMessage":"preferred server not permitted in placement","messagePattern":"preferred server not permitted in placement","errorType":"validation","errorClass":"JSStreamInvalidConfigError","httpStatus":null,"severity":"error","filePath":"server/consumer.go","lineNumber":1027,"sourceCode":"\t\t\t\treturn NewJSConsumerEmptyGroupNameError()\n\t\t\t}\n\t\t\tif !validGroupName.MatchString(group) {\n\t\t\t\treturn NewJSConsumerInvalidGroupNameError()\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// If PriorityPolicy is None or not set, reject if PriorityGroups or PinnedTTL are set\n\t\tif len(config.PriorityGroups) > 0 {\n\t\t\treturn NewJSConsumerPriorityGroupWithPolicyNoneError()\n\t\t}\n\t\tif config.PinnedTTL > 0 {\n\t\t\treturn NewJSConsumerPinnedTTLWithoutPriorityPolicyNoneError()\n\t\t}\n\t}\n\n\t// For now don't allow preferred server in placement.\n\tif cfg.Placement != nil && cfg.Placement.Preferred != _EMPTY_ {\n\t\treturn NewJSStreamInvalidConfigError(fmt.Errorf(\"preferred server not permitted in placement\"))\n\t}\n\n\treturn nil\n}\n\nfunc (mset *stream) addConsumerWithAction(config *ConsumerConfig, action ConsumerAction, pedantic bool) (*consumer, error) {\n\treturn mset.addConsumerWithAssignment(config, _EMPTY_, nil, false, action, pedantic)\n}\n\nfunc (mset *stream) addConsumer(config *ConsumerConfig) (*consumer, error) {\n\treturn mset.addConsumerWithAction(config, ActionCreateOrUpdate, false)\n}\n\nfunc (mset *stream) addConsumerWithAssignment(config *ConsumerConfig, oname string, ca *consumerAssignment, isRecovering bool, action ConsumerAction, pedantic bool) (*consumer, error) {\n\treturn mset.addConsumerWithAssignmentAndMode(config, oname, ca, isRecovering, action, pedantic, false)\n}\n\nfunc (mset *stream) addConsumerForRestore(config *ConsumerConfig) (*consumer, error) {","sourceCodeStart":1009,"sourceCodeEnd":1045,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/consumer.go#L1009-L1045","documentation":"JetStream rejects a consumer or stream config whose Placement block sets a Preferred server. The library explicitly forbids preferred-server placement for consumers for now, treating it as an invalid config. This is a policy restriction in the server, not a transient failure.","triggerScenarios":"Calling AddConsumer (or creating/updating a consumer via js.AddConsumer or stream.AddConsumer with pedantic validation) with cfg.Placement != nil and cfg.Placement.Preferred set to a non-empty server name.","commonSituations":"Copying a stream's placement struct (which may legally carry Preferred) into a consumer config; migrating configs from tooling that assumed placement is fully shared between streams and consumers.","solutions":["Remove the Preferred field from the consumer's Placement config","If server targeting is required, drop Placement entirely and rely on cluster-wide consumer or use streams (where Preferred is allowed)","Set Placement.Preferred to \"\" (empty string) while keeping other placement fields like Tags/Cluster"],"exampleFix":"// before\n cfg.Placement = &Placement{Cluster: \"east\", Preferred: \"nats-1\"}\n// after\n cfg.Placement = &Placement{Cluster: \"east\"}","handlingStrategy":"validation","validationCode":"if cfg.Placement != nil && cfg.Placement.Preferred != \"\" {\n    return fmt.Errorf(\"consumer placement must not set Preferred server\")\n}\n// then call js.AddConsumer(stream, cfg)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never reuse a stream Placement struct for consumer configs without clearing Preferred","Keep a shared constructor that builds consumer placements with Preferred unset","Add a unit test asserting consumer configs never carry Preferred"],"tags":["jetstream","consumer-config","validation"],"backgroundTag":"invalid-stream-or-consumer-config","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}