nats-io/nats-server · error

processRemoteSub Parse Error: '%s'

Error message

processRemoteSub Parse Error: '%s'

What it means

processRemoteSub parses RSUB-style subscription lines from remote connections, including queue-subscription weight fields. When the number of fields doesn't match any supported layout (the switch default), the server cannot map args to subject/queue/weight and rejects the line.

Source

Thrown at server/route.go:1599

	if accInProto {
		subjIdx++
	}
	switch len(args) {
	case subjIdx + 1:
		sub.queue = nil
	case subjIdx + 3:
		sub.queue = args[subjIdx+1]
		sub.qw = int32(parseSize(args[subjIdx+2]))
		// TODO: (ik) We should have a non empty queue name and a queue
		// weight >= 1. For 2.11, we may want to return an error if that
		// is not the case, but for now just overwrite `delta` if queue
		// weight is greater than 1 (it is possible after a reconnect/
		// server restart to receive a queue weight > 1 for a new sub).
		if sub.qw > 1 {
			delta = sub.qw
		}
	default:
		return fmt.Errorf("processRemoteSub Parse Error: '%s'", arg)
	}
	// We know that the number of fields is correct. So we can access args[] based
	// on where we expect the fields to be.

	// If there is an origin, it will be at index 1. The negotiated sentinel
	// denotes leaf interest without an actual origin cluster.
	noOrigin := lnSupport && hasOrigin && bytesToString(args[1]) == leafNoOriginCluster
	if hasOrigin && !noOrigin {
		sub.origin = args[1]
	}
	// For subject, use subjIdx.
	sub.subject = args[subjIdx]
	// If the account name is in the protocol, it will be before the subject.
	if accInProto {
		accountName = bytesToString(args[subjIdx-1])
	}
	// Now set the sub.sid from the arg slice. However, we will have a different
	// one if we use the origin or not.

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Align protocol versions across the cluster/leaf links so all servers send the same sub-line layout
  2. Fix the emitter to include all required fields (subject, queue name, weight, etc.)
  3. Trace the raw line to compare against a compliant server's output
  4. Check for stream corruption shifting field boundaries on earlier frames

Example fix

// before (bridge, queue sub without weight)
"RSUB origin acc subj queue\r\n"
// after
"RSUB origin acc subj queue 1\r\n"
Defensive patterns

Strategy: validation

Validate before calling

// Validate remote SUB line field count against known layouts before sending
layouts := map[int]bool{4: true, 5: true, 6: true} // supported arg counts
if !layouts[len(args)] {
    return fmt.Errorf("unsupported remote SUB arg count %d", len(args))
}

Prevention

When it happens

Trigger: A remote SUB/routed sub line whose field count matches none of the expected cases — e.g. missing weight, extra tokens, or a queue-sub form missing required fields.

Common situations: Queue subscription interest forwarded by a bridge that omits the weight field, version skew between cluster members on the extended sub protocol, or malformed synthetic traffic.

Understand the failure class

Related errors


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