{"record":{"id":"57660d661ab4fd05","repo":"nats-io/nats-server","slug":"priority-timeout-must-not-be-negative","errorCode":null,"errorMessage":"priority_timeout must not be negative","messagePattern":"priority_timeout must not be negative","errorType":"validation","errorClass":"ApiError","httpStatus":null,"severity":"error","filePath":"server/consumer.go","lineNumber":664,"sourceCode":"\t\t\treturn NewJSPedanticError(errors.New(\"max_bytes must not be negative\"))\n\t\t}\n\t\tconfig.MaxRequestMaxBytes = 0\n\t}\n\tif config.Heartbeat < 0 {\n\t\tif pedantic {\n\t\t\treturn NewJSPedanticError(errors.New(\"idle_heartbeat must not be negative\"))\n\t\t}\n\t\tconfig.Heartbeat = 0\n\t}\n\tif config.InactiveThreshold < 0 {\n\t\tif pedantic {\n\t\t\treturn NewJSPedanticError(errors.New(\"inactive_threshold must not be negative\"))\n\t\t}\n\t\tconfig.InactiveThreshold = 0\n\t}\n\tif config.PinnedTTL < 0 {\n\t\tif pedantic {\n\t\t\treturn NewJSPedanticError(errors.New(\"priority_timeout must not be negative\"))\n\t\t}\n\t\tconfig.PinnedTTL = 0\n\t}\n\n\t// Set to default if not specified.\n\tif config.DeliverSubject == _EMPTY_ && config.MaxWaiting == 0 {\n\t\tconfig.MaxWaiting = JSWaitQueueDefaultMax\n\t}\n\t// Setup proper default for ack wait if we are in explicit ack mode.\n\tif config.AckWait == 0 && (config.AckPolicy == AckExplicit || config.AckPolicy == AckAll) {\n\t\tconfig.AckWait = JsAckWaitDefault\n\t}\n\t// If BackOff was specified that will override the AckWait and the MaxDeliver.\n\tif len(config.BackOff) > 0 {\n\t\tif pedantic && config.AckWait != config.BackOff[0] {\n\t\t\treturn NewJSPedanticError(errors.New(\"first backoff value has to equal batch AckWait\"))\n\t\t}\n\t\tconfig.AckWait = config.BackOff[0]","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/consumer.go#L646-L682","documentation":"A JetStream pedantic validation error thrown when PinnedTTL (how long a client may hold a pinned priority-group pull consumer) is negative. The field is the internal representation of the public priority_timeout and must be 0 or positive; pedantic mode rejects rather than clamping at server/consumer.go:664.","triggerScenarios":"ConsumerConfig.PinnedTTL < 0 on consumer create/update with pedantic validation, typically when using priority groups (PriorityGroups/PriorityPolicy) and setting priority_timeout to a negative duration.","commonSituations":"Misreading priority_timeout as a signed 'sticky forever' flag; duration arithmetic errors in priority-group scheduling code; copied config templates with negative placeholder TTLs.","solutions":["Set PinnedTTL / priority_timeout to a positive duration (e.g. 2 * time.Minute) or 0 to disable pinning.","Clamp computed TTLs to >= 0 before assignment.","Only set PinnedTTL when PriorityPolicy/priority groups are configured; otherwise leave 0.","Validate client-side with Validate(true) before the request."],"exampleFix":"// before\ncc := nats.ConsumerConfig{\n    PriorityPolicy: nats.PriorityPinnedClient,\n    PinnedTTL:      -30 * time.Second,\n}\n// after\ncc := nats.ConsumerConfig{\n    PriorityPolicy: nats.PriorityPinnedClient,\n    PinnedTTL:      2 * time.Minute,\n}","handlingStrategy":"validation","validationCode":"if cfg.PinnedTTL < 0 { return errors.New(\"priority_timeout must not be negative\") }\nif cfg.PinnedTTL > 0 && cfg.PriorityPolicy == 0 { return errors.New(\"PinnedTTL requires a PriorityPolicy\") }","typeGuard":null,"tryCatchPattern":"if _, err := js.AddConsumer(stream, &cc); err != nil && strings.Contains(err.Error(), \"priority_timeout\") {\n    cc.PinnedTTL = 0\n    _, err = js.AddConsumer(stream, &cc)\n}","preventionTips":["Set PinnedTTL only together with PriorityPolicy/priority groups and always positive.","Use 0 to disable pinning, never a negative TTL.","Cover priority-group configs with a client-side validation test."],"tags":["jetstream","consumer-config","validation","priority-groups"],"backgroundTag":"invalid-argument-value","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}