nats-io/nats-server · warning

no interest

Error message

no interest

What it means

During a JetStream stream snapshot/backup the server streams chunks to a receiver that must keep an interest in the delivery subject. If the server detects the receiver's subscription is gone (after a 2s grace period), it aborts the snapshot and reports 408 'No Interest'.

Source

Thrown at server/jetstream_api.go:4661

		case <-done:
		}
	})
	defer mset.unsubscribe(ackSub)

	var hdr []byte
	chunk := make([]byte, chunkSize)
	errCh := sr.errCh
	var snapshotErr error
	ackTimer := time.NewTimer(snapshotAckTimeout)
	defer stopAndClearTimer(&ackTimer)
	// index only incremented when a chunk is actually being sent.
	for index := 1; ; {
		select {
		case <-slots:
			// A slot has become available.
		case <-inch:
			// The receiver appears to have gone away.
			snapshotErr = errors.New("no interest")
			hdr = []byte("NATS/1.0 408 No Interest\r\n\r\n")
			goto done
		case err, ok := <-errCh:
			if !ok {
				// Channel closed normally, e.g. on completion.
				errCh = nil
				continue
			}
			// The snapshotting goroutine has failed for some reason.
			snapshotErr = err
			hdr = fmt.Appendf(nil, "NATS/1.0 500 %s\r\n\r\n", err)
			goto done
		case <-ackTimer.C:
			// It's taking a very long time for the receiver to send us acks,
			// they have probably stalled or there is high loss on the link.
			snapshotErr = errors.New("no flow response")
			hdr = []byte("NATS/1.0 408 No Flow Response\r\n\r\n")
			goto done

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Keep the snapshot client's reply-subject subscription alive for the entire snapshot (do not cancel the request early).
  2. Increase client request timeouts so large streams are not abandoned mid-transfer.
  3. Fix connection stability / reconnect handling and re-issue the snapshot.
  4. Retry the snapshot once the receiver is stable; the abort is transient.

Example fix

// before: request may time out and drop interest mid-snapshot
cancelCtx, _ := context.WithTimeout(ctx, 5*time.Second)
snapshotStream(js, "ORDERS", w) // aborted with 'no interest'
// after: allow enough time and keep the subscription alive
snapCtx, _ := context.WithTimeout(ctx, 30*time.Minute)
err := snapshotStream(js, "ORDERS", w)
if err != nil && strings.Contains(err.Error(), "no interest") {
	log.Fatalf("receiver lost interest during snapshot: %v", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// confirm the request context/subscription is alive before snapshotting
if ctx.Err() != nil {
	return fmt.Errorf("snapshot context already cancelled: %w", ctx.Err())
}

Type guard

func isSnapshotNoInterest(err error) bool {
	return err != nil && strings.Contains(err.Error(), "no interest")
}

Try / catch

err := snapshotStream(js, "ORDERS", w)
if isSnapshotNoInterest(err) {
	time.Sleep(time.Second)
	return snapshotStream(js, "ORDERS", w) // receiver dropped interest: re-subscribe and retry
}

Prevention

When it happens

Trigger: The client issuing the snapshot request unsubscribes from or never subscribes to the delivery/reply inbox; the request context is cancelled mid-snapshot; the connection drops, removing the interest.

Common situations: Client-side request timeouts firing during large stream backups; closing the NATS connection mid-snapshot; snapshot helpers that cancel the inbox subscription when the app call returns; network idle timeouts.

Related errors


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