nats-io/nats-server · critical · JSStreamRestoreError

10062

10062

Error message

restore for stream '%s > %s' did not create a stream

What it means

Internal JetStream restore consistency error (wrapped in JSStreamRestoreError, code 10062). After replaying all restore chunks the server expected a materialized stream, but the stream object was nil — the restore transfer 'succeeded' without actually creating the stream.

Source

Thrown at server/jetstream_api.go:4375

				},
				Stream: streamName,
				Start:  start,
				End:    end,
				Bytes:  int64(total),
				Client: ci.forAdvisory(),
				Domain: domain,
			})

			var resp = JSApiStreamCreateResponse{ApiResponse: ApiResponse{Type: JSApiStreamCreateResponseType}}
			if err != nil {
				if IsNatsErr(err, JSStorageResourcesExceededErr, JSMemoryResourcesExceededErr) {
					s.resourcesExceededError(cfg.Storage)
				}
				resp.Error = NewJSStreamRestoreError(err, Unless(err))
				s.Warnf("Restore failed for %s for stream '%s > %s' in %v",
					friendlyBytes(int64(total)), acc.Name, streamName, end.Sub(start))
			} else if mset == nil {
				err = fmt.Errorf("restore for stream '%s > %s' did not create a stream", acc.Name, streamName)
				resp.Error = NewJSStreamRestoreError(err)
				s.Warnf("Restore failed for %s for stream '%s > %s' in %v",
					friendlyBytes(int64(total)), acc.Name, streamName, end.Sub(start))
			} else {
				msetCfg := mset.config()
				resp.StreamInfo = &StreamInfo{
					Created:   mset.createdTime(),
					State:     mset.state(),
					Config:    *setDynamicStreamMetadata(&msetCfg),
					TimeStamp: time.Now().UTC(),
				}
				s.Noticef("Completed restore of %s for stream '%s > %s' in %v",
					friendlyBytes(int64(total)), acc.Name, streamName, end.Sub(start).Round(time.Millisecond))
			}
			if reply != _EMPTY_ {
				s.sendInternalAccountMsg(acc, reply, s.jsonResponse(&resp))
			}
			doneCh <- err

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Retry the restore from the beginning after confirming the stream does not exist
  2. Check nats-server logs ('Restore failed for ...') and cluster state for assignment failures; fix clustering issues first
  3. Delete any partial stream state and re-run the restore; if reproducible, report/upgrade nats-server
Defensive patterns

Strategy: retry

Validate before calling

// pre-check: stream must not exist and cluster must be healthy before restoring
if streamExists(name) || !jetstreamClusterHealthy() {
	return fmt.Errorf("preconditions unmet for restore of %s", name)
}

Try / catch

err := restoreStream(cfg, r)
if err != nil && strings.Contains(err.Error(), "did not create a stream") {
	time.Sleep(backoff)
	deletePartialStream(name)
	return restoreStream(cfg, r) // bounded retry
}

Prevention

When it happens

Trigger: Restore completes all chunk deliveries but stream creation/assignment fails silently or is aborted server-side (e.g. during clustering the meta/asset assignment did not finish), leaving mset nil at the end of the restore handler.

Common situations: Clustered JetStream where the restore's underlying assignment failed or was lost; interrupted restores retried concurrently; server bugs during restore of large streams in clustered mode.

Related errors


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