nats-io/nats-server · error

error in state.json: %w

Error message

error in state.json: %w

What it means

The state.json entry bytes could not be parsed as JSON into StreamState. RestoreStreamV2 wraps the json.Unmarshal error, so the actual syntax/type error is included via %w. This means the snapshot's metadata file is present and readable but not valid stream-state JSON.

Source

Thrown at server/stream_backup.go:267

	dec := s2.NewReader(r)
	tr := archive.NewReader(dec)

	var nstate StreamState

	// Load the stream state.
	hdr, err := tr.Next()
	if err != nil {
		return nil, err
	}
	if hdr.Name != "state.json" {
		return nil, fmt.Errorf("expected state.json first")
	}
	state, err := io.ReadAll(tr)
	if err != nil {
		return nil, fmt.Errorf("expected state.json contents")
	}
	if err := json.Unmarshal(state, &nstate); err != nil {
		return nil, fmt.Errorf("error in state.json: %w", err)
	}

	s, jsa, err := a.checkForJetStream()
	if err != nil {
		return nil, err
	}
	js := jsa.js
	if js == nil {
		return nil, NewJSNotEnabledForAccountError()
	}
	if _, err := a.lookupStream(ncfg.Name); err == nil {
		return nil, NewJSStreamNameExistRestoreFailedError()
	}

	cfg, apiErr := s.checkStreamCfg(ncfg, a, false)
	if apiErr != nil {
		return nil, apiErr
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Read the wrapped JSON error in the message to locate the syntax/type problem and fix state.json (valid JSON, correct StreamState fields)
  2. Re-generate the snapshot from the source stream instead of hand-crafting state.json
  3. Align nats-server versions between backup and restore hosts (use the same or newer restore server that understands the schema)
  4. Validate the file offline: gzip/s2-decompress, extract the first entry, and run it through json.Unmarshal/`go json.tool`

Example fix

// before: hand-edited state.json with a trailing comma
{"FirstSeq": 42, "Msgs": 100,}
// after: valid JSON matching StreamState
{"FirstSeq": 42, "Msgs": 100, "Bytes": 8192, "Consumers": 0}
Defensive patterns

Strategy: validation

Validate before calling

var st StreamState
if err := json.Unmarshal(rawStateJSON, &st); err != nil {
    return fmt.Errorf("state.json invalid: %w", err)
}

Try / catch

var jsErr *json.UnmarshalTypeError
mset, err := acc.RestoreStreamV2(cfg, r)
if err != nil {
    if e, ok := err.(*json.UnmarshalTypeError); ok {
        errors.As(err, &jsErr)
        // e.Field/e.Value pinpoint the bad state.json field
    }
    return err
}

Prevention

When it happens

Trigger: The state.json entry contains invalid JSON: the file was hand-edited, produced by an incompatible server version with a different schema, written by a non-nats tool, or corrupted in a way that survived decompression (bit rot, bad re-encoding, HTML/error page written into the file).

Common situations: Manually editing state.json to tweak FirstSeq/subjects and introducing a syntax error; restoring a snapshot from a much older/newer nats-server with schema drift; a proxy or misconfigured upload writing an error page as the file body; locale/encoding mangling during transfer.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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