{"record":{"id":"55cb7c6d11cca170","repo":"nats-io/nats-server","slug":"10111","errorCode":"10111","errorMessage":"rollup value invalid: %q","messagePattern":"rollup value invalid: %q","errorType":"error_code","errorClass":"JSStreamRollupFailedError","httpStatus":500,"severity":"error","filePath":"server/jetstream_batching.go","lineNumber":946,"sourceCode":"\t\t\tif (!allowRollup || denyPurge) && !sourced {\n\t\t\t\terr := errors.New(\"rollup not permitted\")\n\t\t\t\treturn hdr, msg, 0, NewJSStreamRollupFailedError(err), err\n\t\t\t}\n\t\t\tswitch rollup {\n\t\t\tcase JSMsgRollupSubject:\n\t\t\t\t// Rolling up the subject is only allowed if the first occurrence of this subject in the batch.\n\t\t\t\tif _, ok := diff.inflight[subject]; ok {\n\t\t\t\t\terr := errors.New(\"batch rollup sub invalid\")\n\t\t\t\t\treturn hdr, msg, 0, NewJSStreamRollupFailedError(err), err\n\t\t\t\t}\n\t\t\tcase JSMsgRollupAll:\n\t\t\t\t// Rolling up the whole stream is only allowed if this is the first message of the batch.\n\t\t\t\tif len(diff.inflight) > 0 {\n\t\t\t\t\terr := errors.New(\"batch rollup all invalid\")\n\t\t\t\t\treturn hdr, msg, 0, NewJSStreamRollupFailedError(err), err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\terr := fmt.Errorf(\"rollup value invalid: %q\", rollup)\n\t\t\t\treturn hdr, msg, 0, NewJSStreamRollupFailedError(err), err\n\t\t\t}\n\t\t}\n\t}\n\n\t// Track inflight.\n\t// Store the subject to ensure other messages in this batch using\n\t// an expected check or rollup on the same subject fail.\n\tif diff.inflight == nil {\n\t\tdiff.inflight = make(map[string]*inflightSubjectRunningTotal, 1)\n\t}\n\tvar sz uint64\n\tif mset.store.Type() == FileStorage {\n\t\tsz = fileStoreMsgSizeRaw(len(subject), len(hdr), len(msg))\n\t} else {\n\t\tsz = memStoreMsgSizeRaw(len(subject), len(hdr), len(msg))\n\t}\n\tvar (","sourceCodeStart":928,"sourceCodeEnd":964,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream_batching.go#L928-L964","documentation":"The 'Nats-Rollup' header value was not one of the two accepted values ('sub' to roll up all messages for the subject, 'all' to purge the entire stream). Any other string is rejected before the clustered proposal with JSStreamRollupFailedError (API error 10111). The error quotes the invalid value received.","triggerScenarios":"Setting Nats-Rollup to an unexpected string such as \"Subject\", \"ALL\", \"true\", \"purge\", or a value built via string interpolation; passing a bytes.Header value with trailing whitespace; a client library version mismatch where the rollup constant differs.","commonSituations":"Hand-written header values instead of using the client's MsgId/Rollup helper constants; configuration-driven rollups where a user-facing option string is forwarded verbatim into the header; case sensitivity mistakes (rollup values are lowercase).","solutions":["Set Nats-Rollup to exactly \"sub\" or \"all\" (lowercase, no whitespace)","Use the client library's constants (e.g. nats.MsgRollupSubject / nats.MsgRollupAll in Go) rather than raw strings","Trim/validate any user-provided rollup option before placing it in the header","Remember rollup requires AllowRollup on the stream; fix the value first, then verify stream config if the error changes to a permissions error"],"exampleFix":"// before\nmsg.Header.Set(\"Nats-Rollup\", \"Purge\") // invalid\n// after\nmsg.Header.Set(\"Nats-Rollup\", nats.MsgRollupAll) // \"all\"; use nats.MsgRollupSubject for per-subject rollup","handlingStrategy":"validation","validationCode":"rollup := hdr.Get(\"Nats-Rollup\")\nif rollup != \"\" && rollup != \"sub\" && rollup != \"all\" {\n    return fmt.Errorf(\"invalid rollup value %q: must be \\\"sub\\\" or \\\"all\\\"\", rollup)\n}\n","typeGuard":"func validRollup(v string) bool { return v == \"\" || v == \"sub\" || v == \"all\" }\n","tryCatchPattern":"_, err := js.PublishMsg(msg)\nvar ae *nats.APIError\nif errors.As(err, &ae) && ae.ErrorCode() == 10111 {\n    // reject/normalize the rollup header value before republishing\n}\n","preventionTips":["Use client constants (nats.MsgRollupSubject / nats.MsgRollupAll) instead of raw strings","Trim and lower-case any user-supplied rollup option before setting the header","Verify AllowRollup is enabled on the stream when rollups are intended"],"tags":["jetstream","rollup","header-validation"],"backgroundTag":"invalid-rollup-header","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}