nats-io/nats-server · error · ApiError

max_ack_pending must be set to -1

Error message

max_ack_pending must be set to -1

What it means

This is a JetStream consumer configuration validation error raised in pedantic mode when MaxAckPending is set below -1 (e.g. -5). Unlike other negative values that are silently clamped to 0 in non-pedantic mode, max_ack_pending has a special sentinel value of -1 meaning 'unlimited', so only -1 or non-negative values are valid. In pedantic mode the server rejects the config instead of silently fixing it.

Source

Thrown at server/consumer.go:628

// Helper function to set consumer config defaults from above.
func setConsumerConfigDefaults(config *ConsumerConfig, streamCfg *StreamConfig, lim *JSLimitOpts, accLim *JetStreamAccountLimits, pedantic bool) *ApiError {
	// Setup default of -1, meaning no limit for MaxDeliver.
	if config.MaxDeliver == 0 || config.MaxDeliver < -1 {
		if pedantic && config.MaxDeliver < -1 {
			return NewJSPedanticError(errors.New("max_deliver must be set to -1"))
		}
		config.MaxDeliver = -1
	}
	// Setup zero defaults.
	if config.MaxWaiting < 0 {
		if pedantic {
			return NewJSPedanticError(errors.New("max_waiting must not be negative"))
		}
		config.MaxWaiting = 0
	}
	if config.MaxAckPending < -1 {
		if pedantic {
			return NewJSPedanticError(errors.New("max_ack_pending must be set to -1"))
		}
		config.MaxAckPending = -1
	}
	if config.MaxRequestBatch < 0 {
		if pedantic {
			return NewJSPedanticError(errors.New("max_batch must not be negative"))
		}
		config.MaxRequestBatch = 0
	}
	if config.MaxRequestExpires < 0 {
		if pedantic {
			return NewJSPedanticError(errors.New("max_expires must not be negative"))
		}
		config.MaxRequestExpires = 0
	}
	if config.MaxRequestMaxBytes < 0 {
		if pedantic {
			return NewJSPedanticError(errors.New("max_bytes must not be negative"))

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set MaxAckPending to -1 exactly to request unlimited pending acknowledgments.
  2. Set MaxAckPending to a positive integer (e.g. 1000) or leave it 0 to use the server default/stream limit.
  3. Search your config files/code for negative MaxAckPending assignments and fix the sign.
  4. If you control the client, call config validation (Validate(true)) client-side before sending to catch this early.

Example fix

// before
nc, _ := nats.Connect(nats.DefaultURL)
js, _ := nc.JetStream()
js.AddConsumer("ORDERS", &nats.ConsumerConfig{
    Durable:       "worker",
    MaxAckPending: -10, // invalid: only -1 means unlimited
})
// after
js.AddConsumer("ORDERS", &nats.ConsumerConfig{
    Durable:       "worker",
    MaxAckPending: -1, // unlimited
})
Defensive patterns

Strategy: validation

Validate before calling

func validMaxAckPending(v int) bool { return v >= 0 || v == -1 }
if !validMaxAckPending(cfg.MaxAckPending) { return errors.New("max_ack_pending must be -1 or non-negative") }

Type guard

func isUnlimitedAckPending(v int) bool { return v == -1 }

Try / catch

_, err := js.AddConsumer("ORDERS", &cc)
var apiErr *nats.APIError
if errors.As(err, &apiErr) && strings.Contains(apiErr.Description, "max_ack_pending") {
    cc.MaxAckPending = -1
    _, err = js.AddConsumer("ORDERS", &cc)
}

Prevention

When it happens

Trigger: Creating or updating an ephemeral/durable pull consumer (ConsumerCreate/ConsumerUpdate or js.AddConsumer) with ConsumerConfig.MaxAckPending set to a negative value less than -1 while the request enables pedantic validation (Validate(pedantic=true) path in server/consumer.go:628).

Common situations: Developers intending 'unlimited' pending acks type -10, -100, or misuse a negative constant; config loaded from YAML/JSON where a sign typo slipped in; libraries wrapping the NATS API mapping -1 incorrectly plus an offset.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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