gravitational/teleport · warning

unable to sign with requested key

Error message

unable to sign with requested key

What it means

Manager.TLSSigner (and SSH signing paths) iterate usable key-store backends trying to build a signer from a stored TLS key pair. ErrUnusableKey is returned when no backend can produce a signer for the given key — e.g. the key lives in an HSM/KMS this auth server is not configured to use. It is an expected, sentinel error: callers like lib/auth/init.go treat it as non-fatal (no warning) because a different signer may still exist.

Source

Thrown at lib/auth/keystore/manager.go:457

			return ssh.NewSignerWithAlgorithms(algorithmSigner, []string{ssh.KeyAlgoECDSA256})
		case elliptic.P384():
			return ssh.NewSignerWithAlgorithms(algorithmSigner, []string{ssh.KeyAlgoECDSA384})
		case elliptic.P521():
			return ssh.NewSignerWithAlgorithms(algorithmSigner, []string{ssh.KeyAlgoECDSA521})
		default:
			return nil, trace.BadParameter("SSH CA: ECDSA curve: %s", pub.Curve.Params().Name)
		}
	case ed25519.PublicKey:
		// This is the current default, but let's set it explicitly so
		// golang.org/x/crypto/ssh can't change it in an update and break some
		// HSM or KMS that wouldn't support the new default.
		return ssh.NewSignerWithAlgorithms(algorithmSigner, []string{ssh.KeyAlgoED25519})
	default:
		return nil, trace.BadParameter("SSH CA: unsupported key type: %s", sshSigner.PublicKey().Type())
	}
}

var ErrUnusableKey = errors.New("unable to sign with requested key")

// TLSSigner returns a crypto.Signer for the given TLSKeyPair.
// It returns ErrUnusableKey if unable to create a signer from the given keypair,
// e.g. if it is stored in an HSM or KMS this auth service is not configured to use.
func (m *Manager) TLSSigner(ctx context.Context, keypair *types.TLSKeyPair) (crypto.Signer, error) {
	for _, backend := range m.usableBackends {
		canUse, err := backend.canUseKey(ctx, keypair.Key, keypair.KeyType)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		if !canUse {
			continue
		}
		pub, err := publicKeyFromTLSCertPem(keypair.Cert)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		signer, err := backend.getSigner(ctx, keypair.Key, pub)

View on GitHub (pinned to 1283425b60)

Solutions

  1. Configure the auth server with the keystore backend that holds the key (add the HSM/KMS/PKCS#11 section to auth config) so usableBackends includes it.
  2. Verify errors.Is(err, keystore.ErrUnusableKey) to distinguish expected incompatibility from real failures, as lib/auth/init.go:918 does, and skip silently.
  3. Re-sign or re-issue the CA key pair with a keystore type available to this auth server.

Example fix

// before
signer, err := keyStore.TLSSigner(ctx, kp)
if err != nil {
    return trace.Wrap(err)
}
// after
signer, err := keyStore.TLSSigner(ctx, kp)
if err != nil {
    if errors.Is(err, keystore.ErrUnusableKey) {
        return nil // key managed by an unavailable backend; another signer may cover it
    }
    return trace.Wrap(err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

if !keyStore.SupportsKeyPair(kp) { /* skip; key managed by an unavailable backend */ }

Type guard

if errors.Is(err, keystore.ErrUnusableKey) { /* expected: backend mismatch, not a failure */ }

Try / catch

signer, err := keyStore.TLSSigner(ctx, kp)
switch {
case errors.Is(err, keystore.ErrUnusableKey):
    return nil // benign: another configured signer covers this CA
case err != nil:
    return trace.Wrap(err)
}

Prevention

When it happens

Trigger: Calling keystore Manager.TLSSigner(ctx, keypair) where the key pair was created by a keystore backend (HSM, KMS, PKCS#11) that is absent from the current auth server's usableBackends configuration, so all backends decline and manager.go:483 returns ErrUnusableKey.

Common situations: Auth servers scaled out with different keystore configs (some with HSM/KMS, some without) reading CAs signed elsewhere; HA deployments after migrating CA keys into HSM but not updating all auth servers' keystore config; restore of CA data without the matching keystore plugin configuration.

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/332dd699c2199b75. Report an issue: GitHub.