{"record":{"id":"7aa711d1c97d9d12","repo":"nats-io/nats-server","slug":"v-unable-to-flush-session-v","errorCode":null,"errorMessage":"%v\nunable to flush session: %v","messagePattern":"(.+?)\nunable to flush session: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/tpm/js_ek_tpm_windows.go","lineNumber":219,"sourceCode":"\n// Returns session handle and policy digest.\nfunc policyPCRPasswordSession(rwc io.ReadWriteCloser, pcr int) (sessHandle tpmutil.Handle, policy []byte, retErr error) {\n\tsessHandle, _, err := tpm2.StartAuthSession(\n\t\trwc,\n\t\ttpm2.HandleNull,  /*tpmKey*/\n\t\ttpm2.HandleNull,  /*bindKey*/\n\t\tmake([]byte, 16), /*nonceCaller*/\n\t\tnil,              /*secret*/\n\t\ttpm2.SessionPolicy,\n\t\ttpm2.AlgNull,\n\t\ttpm2.AlgSHA256)\n\tif err != nil {\n\t\treturn tpm2.HandleNull, nil, fmt.Errorf(\"unable to start session: %v\", err)\n\t}\n\tdefer func() {\n\t\tif sessHandle != tpm2.HandleNull && err != nil {\n\t\t\tif err := tpm2.FlushContext(rwc, sessHandle); err != nil {\n\t\t\t\tretErr = fmt.Errorf(\"%v\\nunable to flush session: %v\", retErr, err)\n\t\t\t}\n\t\t}\n\t}()\n\n\tpcrSelection := tpm2.PCRSelection{\n\t\tHash: tpm2.AlgSHA256,\n\t\tPCRs: []int{pcr},\n\t}\n\tif err := tpm2.PolicyPCR(rwc, sessHandle, nil, pcrSelection); err != nil {\n\t\treturn sessHandle, nil, fmt.Errorf(\"unable to bind PCRs to auth policy: %v\", err)\n\t}\n\tif err := tpm2.PolicyPassword(rwc, sessHandle); err != nil {\n\t\treturn sessHandle, nil, fmt.Errorf(\"unable to require password for auth policy: %v\", err)\n\t}\n\tpolicy, err = tpm2.PolicyGetDigest(rwc, sessHandle)\n\tif err != nil {\n\t\treturn sessHandle, nil, fmt.Errorf(\"unable to get policy digest: %v\", err)\n\t}","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/tpm/js_ek_tpm_windows.go#L201-L237","documentation":"Not an independent throw site: it is the deferred cleanup in policyPCRPasswordSession that augments an existing error when flushing the auth session fails during error unwinding. The message is '%v\\nunable to flush session: %v' — the original error plus the flush failure.","triggerScenarios":"An earlier step (PolicyPCR, PolicyPassword, PolicyGetDigest) failed AND the deferred tpm2.FlushContext on the still-open sessHandle also failed.","commonSituations":"TPM became unresponsive mid-operation; connection closed before deferred cleanup ran; rare, secondary failure masking attention from the primary error.","solutions":["Focus on the FIRST line of the error (the original cause); the flush failure is secondary.","Ensure the rwc connection stays open until policyPCRPasswordSession returns.","If flush errors recur, check TPM health/reset the device."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, _, err := policyPCRPasswordSession(rwc, pcr)\nif err != nil {\n\tlines := strings.SplitN(err.Error(), \"\\n\", 2)\n\tlog.Printf(\"primary error: %s\", lines[0]) // flush failure (if any) is line 2\n}","preventionTips":["Keep the TPM connection open until all deferred cleanups complete.","Treat the first error line as the root cause when parsing.","Monitor for repeated flush failures as a sign of TPM hardware issues."],"tags":["tpm","windows","cleanup","deferred-error","go"],"backgroundTag":"tpm-context-flush-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}