nats-io/nats-server · error

unable to persist session %q (seq=%v): invalid pub ack respo

Error message

unable to persist session %q (seq=%v): invalid pub ack response

What it means

Returned when the JetStream publish of the session record succeeds without error but the response is unusable: resp is nil or resp.PubAck is nil, so the new sequence cannot be confirmed. This is a defensive guard against an malformed/missing acknowledgement.

Source

Thrown at server/mqtt.go:3439

		bb := bytes.Buffer{}
		bb.WriteString(hdrLine)
		bb.WriteString(JSExpectedLastSubjSeq)
		bb.WriteString(":")
		bb.WriteString(strconv.FormatInt(int64(seq), 10))
		bb.WriteString(CR_LF)
		bb.WriteString(CR_LF)
		hdr = bb.Len()
		bb.Write(b)
		b = bb.Bytes()
	}

	resp, err := sess.jsa.storeSessionMsg(domainTk, cidHash, hdr, b)
	if err != nil {
		return fmt.Errorf("unable to persist session %q (seq=%v): %v", ps.ID, seq, err)
	}
	// Guard before dereferencing below.
	if resp == nil || resp.PubAck == nil {
		return fmt.Errorf("unable to persist session %q (seq=%v): invalid pub ack response", ps.ID, seq)
	}
	sess.mu.Lock()
	sess.seq = resp.Sequence
	sess.mu.Unlock()
	return nil
}

// Clear the session.
//
// Runs from the client's readLoop.
// Lock not held on entry, but session is in the locked map.
func (sess *mqttSession) clear(noWait bool) error {
	var durs []string
	var pubRelDur string

	sess.mu.Lock()
	id := sess.id
	seq := sess.seq

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Retry the CONNECT / session persistence operation
  2. Upgrade all servers to a consistent version (likely internal bug fixed upstream)
  3. Check JetStream health and logs around the time of the failure
  4. Report/inspect the wrapped scenario: err==nil but PubAck missing

Example fix

// before
// err==nil, resp.PubAck==nil -> error
// after
// upgrade server binaries to matching versions and restart the cluster
null
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await mqttConnect()
} catch (e) {
  if (String(e).includes('invalid pub ack response')) {
    log.error('JetStream returned malformed pub ack; check cluster version consistency', e)
    await mqttConnect() // one retry
  } else { throw e }
}

Prevention

When it happens

Trigger: storeSessionMsg returns resp == nil or resp.PubAck == nil despite err == nil — an unexpected/empty JetStream publish acknowledgement, typically from an API/transport anomaly or a bug in the async pub path.

Common situations: JetStream API returning malformed acks during instability; mixed server versions in a cluster; internal async-publish race.

Related errors


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