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)
returnView on GitHub (pinned to 3a66a489d2)
Solutions
- Upgrade all servers in the cluster to a version that supports the consumer configuration (>= the version that created the consumer).
- Keep server versions homogeneous: complete rolling upgrades promptly and pin the cluster to one release.
- If the new consumer is not needed, delete it from the newer server so the old server can take over the stream.
- 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
- Keep all servers in a JetStream cluster on the same binary version.
- Check `nats server info` versions before joining a node.
- Review release notes for new consumer config features before upgrading only part of the cluster.
- Watch for 'Detected unsupported consumer' warnings in logs during upgrades.
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
- JS_CONSUMER_OFFLINE
- consumer closed
- consumer write error: %v
- max_request_batch must be set if it's JetStream limits are s
- consumer name can not contain '.', '*', '>', '\', '/'
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/619329d248124664.
Report an issue: GitHub.