nats-io/nats-server · error

failed to store message sequence %d: %w

Error message

failed to store message sequence %d: %w

What it means

RestoreStreamV2 stores each valid, non-expired message block via store.StoreRawMsg with its subject, header, payload, sequence, timestamp and TTL. This error wraps any failure from the message store, meaning the raw message could not be written to the destination stream during restore.

Source

Thrown at server/stream_backup.go:541

			}
		}
		lseq = seq
		ttl, err := getMessageTTL(mhdr)
		if err != nil {
			return nil, fmt.Errorf("failed to parse message TTL: %w", err)
		}
		hdrTime := time.Unix(0, hdr.Timestamp)
		if ttl > 0 && time.Now().After(hdrTime.Add(time.Duration(ttl)*time.Second)) {
			// If the TTL has exceeded then there isn't much point in storing the message,
			// but we still need to preserve the sequence.
			if err := store.SkipMsgs(seq, 1); err != nil {
				return nil, fmt.Errorf("failed to process expired message sequence %d: %w", seq, err)
			}
			releaseRestoreBytes(storedSize)
			continue
		}
		if err = store.StoreRawMsg(subj, mhdr, msg, seq, hdr.Timestamp, ttl, false); err != nil {
			return nil, fmt.Errorf("failed to store message sequence %d: %w", seq, err)
		}
		releaseRestoreBytes(storedSize)
	}

	if !eob {
		return mset, fmt.Errorf("backup was truncated")
	}

	// Need to make sure that we pad out with skip msgs to preserve the last
	// sequence, otherwise trailing deleted messages could reuse sequence numbers.
	if lseq < nstate.LastSeq {
		gap := nstate.LastSeq - lseq
		if err := store.SkipMsgs(lseq+1, gap); err != nil {
			return nil, fmt.Errorf("failed to process trailing gap: %w", err)
		}
	}
	return mset, nil
}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Check server logs for the underlying StoreRawMsg error and ensure sufficient disk space
  2. Restore into a new, empty stream (delete the partially restored stream first)
  3. Verify the stream's subjects config covers all subjects present in the backup
  4. Re-create the backup if block data is corrupt (checksum the archive)

Example fix

// before: restoring into existing stream with conflicting state
nats stream restore ORDERS orders.bak
// after: remove conflicting stream state first
nats stream rm ORDERS && nats stream restore ORDERS orders.bak
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: ensure target stream is empty and its subjects cover the backup
for _, s := range backupSubjects {
    if !streamSubjectsMatch(stream.Config.Subjects, s) { return fmt.Errorf("stream does not cover subject %s", s) }
}
if stream.State.Msgs != 0 { return fmt.Errorf("target stream not empty") }

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to store message sequence") {
    // read wrapped cause from server logs: disk full vs subject mismatch vs sequence conflict
}

Prevention

When it happens

Trigger: store.StoreRawMsg returns an error; commonly disk full or I/O failure in the JetStream file store, a subject that violates the stream's configured subject constraints, sequence conflicts with existing stream state, or corrupted block data producing invalid subject/header bytes.

Common situations: Restoring a large backup onto storage without enough space, restoring into a stream whose subjects filter doesn't cover the backup's subjects, or restoring over an existing non-empty stream with conflicting sequences.

Related errors


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