nats-io/nats-server · error
restore for stream '%s > %s' requires reply subject for each
Error message
restore for stream '%s > %s' requires reply subject for each chunk
What it means
JetStream stream restore (file-transfer based restore) protocol error. Every chunk published to the restore delivery subject must carry a reply subject so the server can acknowledge and signal failures/flow control. A chunk without one cancels the restore.
Source
Thrown at server/jetstream_api.go:4258
if err != nil {
pr.CloseWithError(err)
} else {
pr.Close()
}
restoreCh <- struct {
mset *stream
err error
}{
mset: mset,
err: err,
}
})
processChunk := func(sub *subscription, c *client, _ *Account, subject, reply string, msg []byte) {
// We require reply subjects to communicate back failures, flow etc. If they do not have one log and cancel.
if reply == _EMPTY_ {
sub.client.processUnsub(sub.sid)
setResult(fmt.Errorf("restore for stream '%s > %s' requires reply subject for each chunk", acc.Name, streamName), reply)
return
}
// Account client messages have \r\n on end. This is an error.
if len(msg) < LEN_CR_LF {
sub.client.processUnsub(sub.sid)
setResult(fmt.Errorf("restore for stream '%s > %s' received short chunk", acc.Name, streamName), reply)
return
}
// Adjust.
msg = msg[:len(msg)-LEN_CR_LF]
// This means we are complete with our transfer from the client.
if len(msg) == 0 {
s.Debugf("Finished streaming restore for stream '%s > %s'", acc.Name, streamName)
closeWithError(nil)
setResult(nil, reply)
return
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Use nats.Request (request-reply) for each restore chunk instead of Publish
- Ensure every chunk publication includes a non-empty reply subject
- Prefer the client's built-in restore API (jetStream.StreamsRestore / jsm stream restore) over manual chunking
Example fix
// before
js.Publish(restoreSubject, chunk)
// after
js.Restore(&nats.StreamConfig{Name: "S"}) // client handles per-chunk request/reply
// or manually:
resp, err := nc.Request(restoreSubject, chunk, 10*time.Second) Defensive patterns
Strategy: validation
Validate before calling
if reply == "" {
return fmt.Errorf("restore chunk publish must use request-reply (non-empty reply subject)")
} Prevention
- Use nc.Request / js restore APIs, never plain Publish for restore chunks
- Use the official client restore method instead of hand-rolled transfers
When it happens
Trigger: Publishing restore chunks to the $JS.API stream restore subject with Request() replaced by plain Publish, or using a client/subscription that strips the reply subject.
Common situations: Hand-rolled restore implementations over raw NATS; custom tooling that replays recorded restore traffic without reply subjects; intermediate broker/proxy dropping reply fields.
Related errors
- restore for stream '%s > %s' received short chunk
- 10062
- restore for stream '%s > %s' is stalled
- error creating store for stream
- error creating store for consumer
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/ca7da770d3c70d3c.
Report an issue: GitHub.