nats-io/nats-server · error

ErrNoPrivateKeyStoreRef

ErrNoPrivateKeyStoreRef

Error message

unable to obtain private key handle from store

What it means

ErrNoPrivateKeyStoreRef is returned when the library cannot obtain a handle to the certificate's private key in the Windows store. At certstore_windows.go:249 it is returned from the TLSConfig build path when the acquired private key object is nil; at :717 it is returned when CryptAcquireCertificatePrivateKey (or the equivalent NCrypt call) returns 0/failure. This means the certificate exists but no usable private key reference could be obtained.

Source

Thrown at server/certstore/errors.go:24

var (
	// ErrBadCryptoStoreProvider represents inablity to establish link with a certificate store
	ErrBadCryptoStoreProvider = errors.New("unable to open certificate store or store not available")

	// ErrBadRSAHashAlgorithm represents a bad or unsupported RSA hash algorithm
	ErrBadRSAHashAlgorithm = errors.New("unsupported RSA hash algorithm")

	// ErrBadSigningAlgorithm represents a bad or unsupported signing algorithm
	ErrBadSigningAlgorithm = errors.New("unsupported signing algorithm")

	// ErrStoreRSASigningError represents an error returned from store during RSA signature
	ErrStoreRSASigningError = errors.New("unable to obtain RSA signature from store")

	// ErrStoreECDSASigningError represents an error returned from store during ECDSA signature
	ErrStoreECDSASigningError = errors.New("unable to obtain ECDSA signature from store")

	// ErrNoPrivateKeyStoreRef represents an error getting a handle to a private key in store
	ErrNoPrivateKeyStoreRef = errors.New("unable to obtain private key handle from store")

	// ErrExtractingPrivateKeyMetadata represents a family of errors extracting metadata about the private key in store
	ErrExtractingPrivateKeyMetadata = errors.New("unable to extract private key metadata")

	// ErrExtractingECCPublicKey represents an error exporting ECC-type public key from store
	ErrExtractingECCPublicKey = errors.New("unable to extract ECC public key from store")

	// ErrExtractingRSAPublicKey represents an error exporting RSA-type public key from store
	ErrExtractingRSAPublicKey = errors.New("unable to extract RSA public key from store")

	// ErrExtractingPublicKey represents a general error exporting public key from store
	ErrExtractingPublicKey = errors.New("unable to extract public key from store")

	// ErrBadPublicKeyAlgorithm represents a bad or unsupported public key algorithm
	ErrBadPublicKeyAlgorithm = errors.New("unsupported public key algorithm")

	// ErrExtractPropertyFromKey represents a general failure to extract a metadata property field
	ErrExtractPropertyFromKey = errors.New("unable to extract property from key")

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Verify the certificate has an associated private key (certmgr.msc shows a key icon / 'You have a private key that corresponds to this certificate').
  2. Target the correct store (CurrentUser vs LocalMachine) and run with sufficient privileges to read the key.
  3. Re-import the certificate together with its PFX/private key, or insert the smart card holding the key.
  4. Check that the key's KSP is registered and accessible (certutil -repairstore can repair broken key associations).

Example fix

// before: importing only the public certificate
// certutil -addstore My server.cer        -> ErrNoPrivateKeyStoreRef
// after: import cert + key
// certutil -importpfx -user My server.pfx
Defensive patterns

Strategy: validation

Validate before calling

// before building TLS config, verify the cert has an accessible private key
if !hasPrivateKey(cert) { // e.g. via store enumeration / key prov info
    return fmt.Errorf("certificate %s has no accessible private key", cert.Subject)
}

Type guard

func hasStorePrivateKey(cert *x509.Certificate) bool {
    // probe: acquire handle; nil or error means no usable key ref
    pk, err := acquirePrivateKey(cert)
    return err == nil && pk != nil
}

Try / catch

tlsCfg, err := certstore.TLSConfig(cert)
if errors.Is(err, certstore.ErrNoPrivateKeyStoreRef) {
    return fmt.Errorf("install the certificate WITH its private key (import PFX, insert smart card): %w", err)
}

Prevention

When it happens

Trigger: Building a tls.Config via the certstore TLSConfig API on Windows with a certificate that has no linked private key (pk == nil at :249), or CryptAcquireCertificatePrivateKey failing at :717 for a cert whose key lives in an inaccessible store.

Common situations: Importing a .cer file (public part only) without its private key; certificate located in a store the process cannot read (wrong user vs machine store, missing admin rights); smart-card cert whose card is absent; key deleted or migrated after certificate issuance.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/777cf0feaaf6db6f. Report an issue: GitHub.