{"record":{"id":"70e673375250f8e8","repo":"nats-io/nats-server","slug":"unable-to-regenerate-srk-from-the-tpm-v","errorCode":null,"errorMessage":"unable to regenerate SRK from the TPM: %v","messagePattern":"unable to regenerate SRK from the TPM: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/tpm/js_ek_tpm_windows.go","lineNumber":258,"sourceCode":"\n// LoadJetStreamEncryptionKeyFromTPM loads the JetStream encryption key from the TPM.\n// If the keyfile does not exist, a key will be created and sealed. Public and private blobs\n// used to decrypt the key in future sessions will be saved to disk in the file provided.\n// The key will be unsealed and returned only with the correct password and PCR value.\nfunc LoadJetStreamEncryptionKeyFromTPM(srkPassword, jsKeyFile, jsKeyPassword string, pcr int) (string, error) {\n\trwc, err := tpm2.OpenTPM()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not open the TPM: %v\", err)\n\t}\n\tdefer rwc.Close()\n\n\t// Load the key from the TPM\n\tsrkHandle, err := regenerateSRK(rwc, srkPassword)\n\tdefer func() {\n\t\ttpm2.FlushContext(rwc, srkHandle)\n\t}()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to regenerate SRK from the TPM: %v\", err)\n\t}\n\t// Read the keys from the key file. If the filed doesn't exist it means we need to create\n\t// a new js encrytpion key.\n\tpublicBlob, privateBlob, err := readTPMKeysFromFile(jsKeyFile)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tjsek, err := createAndSealJsEncryptionKey(rwc, srkHandle, srkPassword, jsKeyFile, jsKeyPassword, pcr)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"unable to generate new key from the TPM: %v\", err)\n\t\t\t}\n\t\t\t// we've created and sealed the JS Encryption key, now we just return it.\n\t\t\treturn jsek, nil\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"unable to load key from TPM: %v\", err)\n\t}\n\n\t// Unseal the JetStream encryption key using the TPM.\n\tjsek, err := unsealJsEncrpytionKey(rwc, pcr, srkHandle, srkPassword, jsKeyPassword, publicBlob, privateBlob)","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/tpm/js_ek_tpm_windows.go#L240-L276","documentation":"Wraps the error returned by regenerateSRK() while rebuilding the Storage Root Key handle inside LoadJetStreamEncryptionKeyFromTPM. It fires when the TPM rejects the SRK regeneration, typically because the supplied SRK password is wrong or the TPM is in a bad/unavailable state, aborting retrieval of the JetStream encryption key.","triggerScenarios":"Thrown at server/tpm/js_ek_tpm_windows.go:258 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the srkPassword passed to LoadJetStreamEncryptionKeyFromTPM matches the one used when the SRK was originally created","Check TPM availability and health (tpm2.OpenTPM already succeeded, so confirm the device is responsive)","If the SRK cannot be recovered, re-provision the TPM and recreate the sealed JetStream key","Retry after confirming no other process holds exclusive access to the TPM"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}