nats-io/nats-server · error · ApiError

max_request_batch must be set if it's JetStream limits are s

Error message

max_request_batch must be set if it's JetStream limits are set

What it means

When creating a consumer whose JetStream limits include MaxRequestBatch (>0) but the consumer config does not set MaxRequestBatch, the server flags a pedantic configuration error. In non-pedantic mode the server silently copies lim.MaxRequestBatch into the config; with pedantic mode enabled it refuses and returns this error instead. It only applies to pull consumers (DeliverSubject is empty).

Source

Thrown at server/consumer.go:710

			return NewJSPedanticError(errors.New("inactive_threshold must be set if it's configured in stream limits"))
		}
		config.InactiveThreshold = streamCfg.ConsumerLimits.InactiveThreshold
	}
	// Set proper default for max ack pending if we are ack explicit and none has been set.
	if config.MaxAckPending == 0 && config.AckPolicy != AckNone {
		ackPending := JsDefaultMaxAckPending
		if lim.MaxAckPending > 0 && lim.MaxAckPending < ackPending {
			ackPending = lim.MaxAckPending
		}
		if accLim.MaxAckPending > 0 && accLim.MaxAckPending < ackPending {
			ackPending = accLim.MaxAckPending
		}
		config.MaxAckPending = ackPending
	}
	// if applicable set max request batch size
	if config.DeliverSubject == _EMPTY_ && config.MaxRequestBatch == 0 && lim.MaxRequestBatch > 0 {
		if pedantic {
			return NewJSPedanticError(errors.New("max_request_batch must be set if it's JetStream limits are set"))
		}
		config.MaxRequestBatch = lim.MaxRequestBatch
	}

	// set the default value only if pinned policy is used.
	if config.PriorityPolicy == PriorityPinnedClient && config.PinnedTTL == 0 {
		config.PinnedTTL = JsDefaultPinnedTTL
	}

	// Set default values for flow control policy.
	if config.AckPolicy == AckFlowControl && !pedantic {
		config.FlowControl = true
		config.Heartbeat = sourceHealthHB
	}
	return nil
}

// Check the consumer config. If we are recovering don't check filter subjects.

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set MaxRequestBatch explicitly in the ConsumerConfig before creating the consumer.
  2. Remove MaxRequestBatch from the account/stream limits if you do not need batch size capping.
  3. Run the server without pedantic mode so the value is defaulted automatically.
  4. Upgrade or align client library so consumer creation templates include MaxRequestBatch.

Example fix

// before
js.AddConsumer(stream, &nats.ConsumerConfig{Durable: "worker"})
// after
js.AddConsumer(stream, &nats.ConsumerConfig{Durable: "worker", MaxRequestBatch: 100})
Defensive patterns

Strategy: validation

Validate before calling

func validateMaxRequestBatch(cfg *nats.ConsumerConfig, limMaxRequestBatch int, pedantic bool) error {
	if cfg.DeliverSubject == "" && cfg.MaxRequestBatch == 0 && limMaxRequestBatch > 0 {
		if pedantic {
			return errors.New("max_request_batch must be set when JetStream limits define it (pedantic mode)")
		}
		cfg.MaxRequestBatch = limMaxRequestBatch // mirror server defaulting
	}
	return nil
}

Prevention

When it happens

Trigger: Calling ConsumerCreate/AddConsumer (via $JS.API.CONSUMER.CREATE or client APIs like js.AddConsumer) with a JetStream limit requester context that sets MaxRequestBatch>0, DeliverSubject empty (pull consumer), config.MaxRequestBatch==0, and the server/level running with --js pedantic checks enabled.

Common situations: Using a JetStream domain/account limits template that specifies max_request_batch while the application creates pull consumers without explicitly setting MaxRequestBatch; environments where the server runs with pedantic mode (used in NATS conformance/strict deployments) after migrating from non-pedantic servers that auto-filled the value.

Related errors


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