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
- Check server logs for the underlying StoreRawMsg error and ensure sufficient disk space
- Restore into a new, empty stream (delete the partially restored stream first)
- Verify the stream's subjects config covers all subjects present in the backup
- 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
- Always restore into a new, empty stream
- Verify stream subject filters include all backup subjects
- Provision storage headroom for the full backup size
- Confirm disk space before starting long restores
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
- failed to process gap: %w
- failed to process expired message sequence %d: %w
- failed to process trailing gap: %w
- storage type can not be updated
- error creating store for stream
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/446965f9f04c2710.
Report an issue: GitHub.