nats-io/nats-server · error · JSStreamRollupFailedError

10111

10111

Error message

rollup value invalid: %q

What it means

A rollup publish request carried a Nats-Rollup header value that JetStream does not recognize (only JSMsgRollupSubject "sub" and JSMsgRollupAll "all" are valid). When consistency checking is possible, the server builds this error and returns it in the PubAck's Error field as a JSStreamRollupFailedError (code 10111). The odd DECLARED/USED AT metadata refers to conf/fuzz.go where a same-named 'err' variable appears in a config parser fuzzer, unrelated to the stream.go throw site.

Source

Thrown at server/stream.go:6941

		if rollup := getRollup(hdr); rollup != _EMPTY_ {
			if canConsistencyCheck && !allowRollupPurge && !sourced {
				err := errors.New("rollup not permitted")
				if canRespond {
					resp.PubAck = &PubAck{Stream: name}
					resp.Error = NewJSStreamRollupFailedError(err)
					b, _ := json.Marshal(resp)
					outq.sendMsg(reply, b)
				}
				return err
			}
			switch rollup {
			case JSMsgRollupSubject:
				rollupSub = true
			case JSMsgRollupAll:
				rollupAll = true
			default:
				if canConsistencyCheck {
					err := fmt.Errorf("rollup value invalid: %q", rollup)
					if canRespond {
						resp.PubAck = &PubAck{Stream: name}
						resp.Error = NewJSStreamRollupFailedError(err)
						b, _ := json.Marshal(resp)
						outq.sendMsg(reply, b)
					}
					return err
				}
			}
		}
	}

	if canConsistencyCheck && incr == nil && allowMsgCounter {
		apiErr := NewJSMessageIncrMissingError()
		if canRespond {
			resp.PubAck = &PubAck{Stream: name}
			resp.Error = apiErr
			b, _ := json.Marshal(resp)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set the Nats-Rollup header to exactly "sub" or "all" (use library constants nats.MsgRollupSubject / nats.MsgRollupAll).
  2. Check AllowRollupHeaders is enabled on the target stream.
  3. Inspect the PubAck.Error / NoResponders path in your publish helper for header typos.

Example fix

// before
msg.Header.Set("Nats-Rollup", "All")
// after
msg.Header.Set("Nats-Rollup", nats.MsgRollupAll) // "all"
Defensive patterns

Strategy: type-guard

Validate before calling

switch rollup {
case nats.MsgRollupSubject, nats.MsgRollupAll:
    // ok
default:
    return fmt.Errorf("invalid rollup header %q", rollup)
}

Type guard

func isRollupValue(v string) bool {
    return v == "sub" || v == "all"
}

Try / catch

if pa.Err != nil && pa.Err.ErrorCode == 10111 { /* invalid rollup header value */ }

Prevention

When it happens

Trigger: Publishing with msg header Nats-Rollup set to something other than 'sub' or 'all' (case-sensitive) against a stream with AllowRollupHeaders enabled.

Common situations: Hand-rolled header constants (e.g. 'Rollup' or 'ALL' with wrong case), proxy middleware injecting rollup headers incorrectly, or older client libraries building the header manually.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/9f31e1f01a60dec9. Report an issue: GitHub.