nats-io/nats-server · error

unsupported consumer %q

Error message

unsupported consumer %q

What it means

During consumer assignment recovery, a NATS server detects a consumer config/feature from a newer server version that this server does not support (ca.unsupported is set). The server logs a warning, subscribes for info updates, and marks the parent stream assignment as unsupported with the error `unsupported consumer %q`, so the whole stream is protected from modification rather than operating on partially-understood state.

Source

Thrown at server/jetstream_cluster.go:6643

	// Capture the optional state. We will pass it along if we are a member to apply.
	// This is only applicable when restoring a stream with consumers.
	state := ca.State
	ca.State = nil

	// Place into our internal map under the stream assignment.
	// Ok to replace an existing one, we check on process call below.
	sa.consumers[ca.Name] = ca
	cc.removeInflightConsumerProposal(accName, stream, consumerName)

	// If unsupported, we can't register any further.
	if ca.unsupported != nil {
		ca.unsupported.setupInfoSub(s, ca)
		s.Warnf("Detected unsupported consumer '%s > %s > %s': %s", accName, stream, ca.Name, ca.unsupported.reason)

		// Mark stream as unsupported as well
		if sa.unsupported == nil {
			sa.unsupported = newUnsupportedStreamAssignment(s, sa, fmt.Errorf("unsupported consumer %q", ca.Name))
		}
		sa.unsupported.setupInfoSub(s, sa)
		js.mu.Unlock()

		// Be conservative by protecting the whole stream, even if just one consumer is unsupported.
		// This ensures it's safe, even with Interest-based retention where it would otherwise
		// continue accepting but dropping messages.
		acc, err := s.lookupOrFetchAccount(accName, isMember)
		if err != nil {
			return
		}
		mset, err := acc.lookupStream(stream)
		if err != nil || mset.closed.Load() {
			return
		}
		s.Warnf("Stopping unsupported stream '%s > %s'", accName, stream)
		mset.stop(false, false)
		return

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Upgrade all servers in the cluster to a version that supports the consumer configuration (>= the version that created the consumer).
  2. Keep server versions homogeneous: complete rolling upgrades promptly and pin the cluster to one release.
  3. If the new consumer is not needed, delete it from the newer server so the old server can take over the stream.
  4. Check the warning log line ('Detected unsupported consumer ...') for the exact unsupported reason.

Example fix

// before: mixed cluster
$ nats-server -c nats.conf   # v2.9 binary joining v2.10 peers
// after: upgrade the old node first
$ nats-server --version && go install github.com/nats-io/nats-server/v2@latest
$ nats-server -c nats.conf   # all nodes on same version
Defensive patterns

Strategy: validation

Validate before calling

// compare server versions before forming a cluster
if serverVersion < minVersionThatCreatedConsumers {
    upgradeBeforeJoining()
}

Prevention

When it happens

Trigger: A server running an older nats-server version joins or restarts in a cluster (or recovers a stream assignment file) where another, newer server created a consumer using newer configuration options or features (e.g. new consumer config fields, priority groups, metadata) that the older binary cannot parse.

Common situations: Mixed-version clusters during upgrades; rolling restarts where one node is on an old release; restoring a stream (RA3/mirror/sourced or backup) created by a newer server.

Related errors


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