nats-io/nats-server · error

unable to create/access directory %q: %v

Error message

unable to create/access directory %q: %v

What it means

Emitted on Windows during JetStream TPM key setup: the directory that should hold the persisted TPM-sealed key blobs could not be created or accessed (os.MkdirAll/open failure). Typical causes are insufficient NTFS permissions for the service account, an invalid path, or the directory being locked by another process; without it the sealed key material cannot be written.

Source

Thrown at server/tpm/js_ek_tpm_windows.go:88

		},
	}
	// Create the parent key against which to seal the data
	srkHandle, _, err := tpm2.CreatePrimary(rwc, tpm2.HandleOwner, tpm2.PCRSelection{}, "", srkPassword, srkTemplate)
	return srkHandle, err
}

type natsTPMPersistedKeys struct {
	Version    int    `json:"version"`
	PrivateKey []byte `json:"private_key"`
	PublicKey  []byte `json:"public_key"`
}

// Writes the private and public blobs to disk in a single file. If the directory does
// not exist, it will be created. If the file already exists it will be overwritten.
func writeTPMKeysToFile(filename string, privateBlob []byte, publicBlob []byte) error {
	keyDir := filepath.Dir(filename)
	if err := os.MkdirAll(keyDir, 0750); err != nil {
		return fmt.Errorf("unable to create/access directory %q: %v", keyDir, err)
	}

	// Create a new set of persisted keys. Note that the private key doesn't necessarily
	// need to be protected as the TPM password is required to use unseal, although it's
	// a good idea to put this in a secure location accessible to the server.
	tpmKeys := natsTPMPersistedKeys{
		Version:    JsKeyTPMVersion,
		PrivateKey: make([]byte, base64.StdEncoding.EncodedLen(len(privateBlob))),
		PublicKey:  make([]byte, base64.StdEncoding.EncodedLen(len(publicBlob))),
	}
	base64.StdEncoding.Encode(tpmKeys.PrivateKey, privateBlob)
	base64.StdEncoding.Encode(tpmKeys.PublicKey, publicBlob)
	// Convert to JSON
	keysJSON, err := json.Marshal(tpmKeys)
	if err != nil {
		return fmt.Errorf("unable to marshal keys to JSON: %v", err)
	}
	// Write the JSON to a file

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Check that the NATS service account has create/write permission on the parent directory (commonly under ProgramData)
  2. Remove stale lock files or permissions overrides on the target directory
  3. Manually create the directory with correct ACLs, then restart the server so key sealing can proceed
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at server/tpm/js_ek_tpm_windows.go:88 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/8c7792b2c918a4d5. Report an issue: GitHub.