{"record":{"id":"5eb02917a5bbb789","repo":"nats-io/nats-server","slug":"10094","errorCode":"10094","errorMessage":"consumer delivery policy is deliver last per subject, but FilterSubject is not set","messagePattern":"consumer delivery policy is deliver last per subject, but FilterSubject is not set","errorType":"error_code","errorClass":"JSConsumerInvalidPolicyError","httpStatus":400,"severity":"error","filePath":"server/jetstream_cluster.go","lineNumber":11435,"sourceCode":"\t\t\t\t\t\ttotal++\n\t\t\t\t\t\tif selectedTier == _EMPTY_ || isSameTier(ca.Config.replicas(&streamCfg), selectedReplicas) {\n\t\t\t\t\t\t\ttierTotal++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (streamMaxc > 0 && total >= streamMaxc) || (tierMaxc > 0 && tierTotal >= tierMaxc) {\n\t\t\t\t\tresp.Error = NewJSMaximumConsumersLimitError()\n\t\t\t\t\ts.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Also short circuit if DeliverLastPerSubject is set with no FilterSubject.\n\tif cfg.DeliverPolicy == DeliverLastPerSubject {\n\t\tif cfg.FilterSubject == _EMPTY_ && len(cfg.FilterSubjects) == 0 {\n\t\t\tresp.Error = NewJSConsumerInvalidPolicyError(fmt.Errorf(\"consumer delivery policy is deliver last per subject, but FilterSubject is not set\"))\n\t\t\ts.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Setup proper default for ack wait if we are in explicit ack mode.\n\tif cfg.AckWait == 0 && (cfg.AckPolicy == AckExplicit || cfg.AckPolicy == AckAll) {\n\t\tcfg.AckWait = JsAckWaitDefault\n\t}\n\t// Setup default of -1, meaning no limit for MaxDeliver.\n\tif cfg.MaxDeliver == 0 {\n\t\tcfg.MaxDeliver = -1\n\t}\n\t// Set proper default for max ack pending if we are ack explicit and none has been set.\n\tif cfg.AckPolicy == AckExplicit && cfg.MaxAckPending == 0 {\n\t\tcfg.MaxAckPending = JsDefaultMaxAckPending\n\t}\n","sourceCodeStart":11417,"sourceCodeEnd":11453,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream_cluster.go#L11417-L11453","documentation":"JSConsumerInvalidPolicyError (API error 10094): the consumer create/update handler rejects a configuration whose DeliverPolicy is DeliverLastPerSubject without any subject filter. DeliverLastPerSubject needs a filter to know which subjects to track; with no FilterSubject/FilterSubjects it is an unresolvable policy, so the request fails.","triggerScenarios":"Creating a consumer (push or pull) via `$JS.API.CONSUMER.CREATE.*`, `jetstream.CreateConsumer`, or `js.AddConsumer` with `DeliverPolicy: DeliverLastPerSubject` while leaving `FilterSubject` empty (and no `FilterSubjects`).","commonSituations":"Copy-pasted consumer configs where the filter was removed; code paths that compute the deliver policy dynamically but only sometimes set a filter; tooling migrating consumers to 'last per subject' semantics.","solutions":["Set FilterSubject (e.g. `orders.>`) in the consumer config, or add entries to FilterSubjects.","If no filter is wanted, switch DeliverPolicy to DeliverLast or DeliverAll instead of DeliverLastPerSubject.","Add a pre-submission validation that pairs DeliverLastPerSubject with a non-empty filter."],"exampleFix":"// before\ncc := &nats.ConsumerConfig{DeliverPolicy: nats.DeliverLastPerSubject}\n// after\ncc := &nats.ConsumerConfig{\n    DeliverPolicy: nats.DeliverLastPerSubject,\n    FilterSubject: \"events.>\",\n}","handlingStrategy":"validation","validationCode":"// Go client: guard before creating the consumer\nif cc.DeliverPolicy == nats.DeliverLastPerSubject && cc.FilterSubject == \"\" && len(cc.FilterSubjects) == 0 {\n    return errors.New(\"DeliverLastPerSubject requires FilterSubject or FilterSubjects\")\n}","typeGuard":"func validDeliverLastPerSubject(cc *nats.ConsumerConfig) bool {\n    if cc.DeliverPolicy != nats.DeliverLastPerSubject {\n        return true\n    }\n    return cc.FilterSubject != \"\" || len(cc.FilterSubjects) > 0\n}","tryCatchPattern":"_, err := js.CreateConsumer(nc, stream, cfg)\nvar apiErr *nats.APIError\nif errors.As(err, &apiErr) && apiErr.ErrorCode == 10094 {\n    cfg.FilterSubject = \"events.>\" // or switch DeliverPolicy\n    _, err = js.CreateConsumer(nc, stream, cfg)\n}","preventionTips":["Always pair DeliverLastPerSubject with an explicit subject filter.","Use a config struct wrapper that validates deliver policy/filter combinations.","Lint consumer configs in CI before deployment.","Default to DeliverLast/DeliverAll when no filter is needed."],"tags":["jetstream","consumer","config-validation","api-error"],"backgroundTag":"invalid-consumer-policy","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}