{"record":{"id":"665d891a14511083","repo":"nats-io/nats-server","slug":"unable-to-write-key-file-v","errorCode":null,"errorMessage":"unable to write key file: %v","messagePattern":"unable to write key file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/tpm/js_ek_tpm_windows.go","lineNumber":171,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"unable to flush session: %v\", err)\n\t}\n\t// Seal the data to the parent key and the policy\n\tuser, err := nkeys.CreateUser()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to create seed: %v\", err)\n\t}\n\t// We'll use the seed to represent the encryption key.\n\tjsStoreKey, err := user.Seed()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to get seed: %v\", err)\n\t}\n\tprivateArea, publicArea, err := tpm2.Seal(rwc, srkHandle, srkPassword, jsKeyPassword, policy, jsStoreKey)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to seal data: %v\", err)\n\t}\n\terr = writeTPMKeysToFile(jsKeyFile, privateArea, publicArea)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to write key file: %v\", err)\n\t}\n\treturn string(jsStoreKey), nil\n}\n\n// Unseals the JetStream encryption key from the TPM with the provided keys.\n// The key is returned as a string.\nfunc unsealJsEncrpytionKey(rwc io.ReadWriteCloser, pcr int, srkHandle tpmutil.Handle, srkPassword, objectPassword string, publicBlob, privateBlob []byte) (string, error) {\n\t// Load the public/private blobs into the TPM for decryption.\n\tobjectHandle, _, err := tpm2.Load(rwc, srkHandle, srkPassword, publicBlob, privateBlob)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to load data: %v\", err)\n\t}\n\tdefer tpm2.FlushContext(rwc, objectHandle)\n\n\t// Create the authorization session with TPM.\n\tsessHandle, _, err := policyPCRPasswordSession(rwc, pcr)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to get auth session: %v\", err)","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/tpm/js_ek_tpm_windows.go#L153-L189","documentation":"After a successful tpm2.Seal, the returned private and public blobs could not be persisted to the JetStream key file on disk. The wrapping writeTPMKeysToFile error (permissions, path, disk space) is embedded in %v.","triggerScenarios":"writeTPMKeysToFile(jsKeyFile, privateArea, publicArea) fails — bad jsKeyFile path, unwritable directory, disk full, or the parent directory doesn't exist.","commonSituations":"Running under a service account lacking write permission to the configured key file directory; jsKeyFile path misconfigured; read-only filesystem or container volume.","solutions":["Read the embedded %v cause to identify the OS-level file error.","Verify the directory containing jsKeyFile exists and the process user has write permission.","Create the parent directory before calling LoadJetStreamEncryptionKeyFromTPM.","Check disk space and that the path isn't on a read-only mount."],"exampleFix":"// before: directory may not exist\nerr = writeTPMKeysToFile(jsKeyFile, privateArea, publicArea)\n// after: ensure directory exists first\nif err := os.MkdirAll(filepath.Dir(jsKeyFile), 0o700); err != nil {\n\treturn \"\", fmt.Errorf(\"unable to create key dir: %v\", err)\n}\nerr = writeTPMKeysToFile(jsKeyFile, privateArea, publicArea)","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(jsKeyFile)\nif info, err := os.Stat(dir); err != nil || !info.IsDir() {\n\treturn fmt.Errorf(\"key file directory %q missing\", dir)\n}\ntest, err := os.CreateTemp(dir, \".writecheck\")\nif err != nil {\n\treturn fmt.Errorf(\"directory %q not writable: %w\", dir, err)\n}\ntest.Close()\nos.Remove(test.Name())","typeGuard":null,"tryCatchPattern":"if err != nil {\n\tif os.IsPermission(err) {\n\t\tlog.Printf(\"permission denied writing key file %s: %v\", jsKeyFile, err)\n\t}\n\treturn err\n}","preventionTips":["Create the key file directory with MkdirAll(0o700) at startup.","Run the service under an account with write access to the key directory.","Check free disk space before writing.","Keep key file paths out of read-only mounts/containers."],"tags":["tpm","windows","filesystem","key-file","go"],"backgroundTag":"file-write-permission-denied","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}