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
- Read the wrapped JSON error in the message to locate the syntax/type problem and fix state.json (valid JSON, correct StreamState fields)
- Re-generate the snapshot from the source stream instead of hand-crafting state.json
- Align nats-server versions between backup and restore hosts (use the same or newer restore server that understands the schema)
- 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
- Never hand-edit state.json; regenerate snapshots instead
- Run snapshot JSON through a validator before restoring across versions
- Keep backup/restore nats-server versions aligned
- Reject snapshots whose state.json fails offline unmarshal into StreamState
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
- failed to decode consumer %q state: %w
- JS_INVALID_JSON
- unknown consumer action: %v
- unknown priority policy: %v
- flush of last block failed: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c10a308067456e25.
Report an issue: GitHub.