nats-io/nats-server · error
unable to unmarshal TPM file keys JSON from %s: %v
Error message
unable to unmarshal TPM file keys JSON from %s: %v
What it means
readTPMKeysFromFile read the JetStream TPM keys file but json.Unmarshal could not parse it into natsTPMPersistedKeys. This means the file exists yet is corrupt, truncated, empty, or was written by an incompatible version — so the sealed key blobs cannot be recovered from disk and unsealing cannot proceed.
Source
Thrown at server/tpm/js_ek_tpm_windows.go:123
func readTPMKeysFromFile(filename string) ([]byte, []byte, error) {
keysJSON, err := os.ReadFile(filename)
if err != nil {
return nil, nil, err
}
var tpmKeys natsTPMPersistedKeys
if err := json.Unmarshal(keysJSON, &tpmKeys); err != nil {
return nil, nil, fmt.Errorf("unable to unmarshal TPM file keys JSON from %s: %v", filename, err)
}
// Base64 decode the private and public blobs.
privateBlob := make([]byte, base64.StdEncoding.DecodedLen(len(tpmKeys.PrivateKey)))
publicBlob := make([]byte, base64.StdEncoding.DecodedLen(len(tpmKeys.PublicKey)))
prn, err := base64.StdEncoding.Decode(privateBlob, tpmKeys.PrivateKey)
if err != nil {
return nil, nil, fmt.Errorf("unable to decode privateBlob from base64: %v", err)
}
return publicBlob, privateBlob, nil
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Inspect the keys file at the reported path for truncation or corruption
- Delete the corrupt key file and restart so a new key is created and sealed (note: previously encrypted JetStream data will be unrecoverable)
- Restore the file from backup if one exists
- Confirm the file was not modified by another process or written by an incompatible NATS version
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at server/tpm/js_ek_tpm_windows.go:123 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/68ac2d501e054295.
Report an issue: GitHub.