nats-io/nats-server · error

ErrStoreRSASigningError

ErrStoreRSASigningError

Error message

unable to obtain RSA signature from store

What it means

ErrStoreRSASigningError is returned when the Windows CNG call NCryptSignHash (with winBCryptPadPKCS1 padding) fails — the syscall returns a nonzero NTSTATUS/NTSTATUS-like result. The library asked the Windows certificate store / key storage provider to produce an RSA signature over a hash, and Windows refused. Unlike the Bad* errors, the hash algorithm and options were valid; the failure is inside the OS key operation.

Source

Thrown at server/certstore/errors.go:18

package certstore

import (
	"errors"
)

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")

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Re-open the certificate store and re-acquire the private key handle (handles can go stale), then retry the handshake.
  2. Confirm the certificate's private key has the Digital Signature key usage and is accessible (certmgr.msc -> key is present, smart card inserted).
  3. Check Windows Event Viewer / NCrypt error code returned by the underlying call for the specific KSP failure reason.
  4. Test signing with a software-backed key to isolate whether the KSP/TPM/smart card is the problem.

Example fix

// before: long-lived cached signer over a smart-card key that was re-inserted
sig, err := cachedSigner.Sign(rand, digest, crypto.SHA256)
// after: reacquire the key before signing
store, err := certstore.Open(...) // reopen and get a fresh TLSConfig/signer
sig, err := freshSigner.Sign(rand, digest, crypto.SHA256)
Defensive patterns

Strategy: retry

Validate before calling

// validate before handshake: key present and has digital-signature usage
if key, err := certstore.AcquirePrivateKeyHandle(cert); err != nil || key == nil {
    return fmt.Errorf("RSA key handle not usable: %v", err)
}

Type guard

func isStoreSigningError(err error) bool {
    return errors.Is(err, certstore.ErrStoreRSASigningError) ||
        errors.Is(err, certstore.ErrStoreECDSASigningError)
}

Try / catch

sig, err := signer.Sign(rand, digest, crypto.SHA256)
if errors.Is(err, certstore.ErrStoreRSASigningError) {
    // reacquire handle and retry once
    signer = reacquireSigner(cert)
    sig, err = signer.Sign(rand, digest, crypto.SHA256)
}

Prevention

When it happens

Trigger: TLSConfig-configured store-backed RSA key signing via Sign -> NCryptSignHash returning r != 0 at certstore_windows.go:633 or :648 — i.e. the private key handle is stale/revoked, the key is non-exportable with disallowed usage, the smart card is removed, or PKCS1 padding is rejected by the KSP.

Common situations: Smart-card or TPM-based certificates where the card is removed or locked; certificate private keys with restricted key-usage (no digital signature); keys whose handles went stale after the store was reopened; HSM/KSP denying the operation for policy reasons.

Related errors


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