hashicorp/nomad · error
invalid key type: %T
Error message
invalid key type: %T
What it means
keyID was given a public key whose concrete Go type is neither *ecdsa.PublicKey nor *rsa.PublicKey, so the switch falls through to the default and refuses to compute an RFC 5280 Subject Key Identifier. This is a programming error in the caller, not a data-corruption issue.
Source
Thrown at helper/tlsutil/generate.go:267
return "", "", err
}
var buf bytes.Buffer
err = pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: bs})
if err != nil {
return "", "", fmt.Errorf("error encoding private key: %s", err)
}
return buf.String(), pk, nil
}
// KeyId returns a x509 KeyId from the given signing key.
func keyID(raw interface{}) ([]byte, error) {
switch raw.(type) {
case *ecdsa.PublicKey:
case *rsa.PublicKey:
default:
return nil, fmt.Errorf("invalid key type: %T", raw)
}
// This is not standard; RFC allows any unique identifier as long as they
// match in subject/authority chains but suggests specific hashing of DER
// bytes of public key including DER tags.
bs, err := x509.MarshalPKIXPublicKey(raw)
if err != nil {
return nil, err
}
// String formatted
kID := sha256.Sum256(bs)
return kID[:], nil
}
// ParseCert parses the x509 certificate from a PEM-encoded value.
func ParseCert(pemValue string) (*x509.Certificate, error) {
// The _ result below is not an error but the remaining PEM bytes.View on GitHub (pinned to 482b49bf1a)
Solutions
- Pass the public key (e.g. signer.Public()) rather than the private key to keyID.
- Use an ECDSA (P-256) or RSA private key when generating CAs/certs with this helper.
- If you need Ed25519, extend keyID's switch to handle *ed25519.PublicKey.
- Verify any custom crypto.Signer implementation's Public() returns *ecdsa.PublicKey or *rsa.PublicKey.
Example fix
// before signer := ed25519.GenerateKey(rand.Reader) kid, err := keyID(signer) // after ecdsaKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) kid, err := keyID(&ecdsaKey.PublicKey)
Defensive patterns
Strategy: type-guard
Validate before calling
func isSupportedSigner(s crypto.Signer) error {
switch s.Public().(type) {
case *ecdsa.PublicKey, *rsa.PublicKey:
return nil
default:
return fmt.Errorf("unsupported key type %T; use ECDSA or RSA", s.Public())
}
} Type guard
func isSupportedPublicKey(pub interface{}) bool {
switch pub.(type) {
case *ecdsa.PublicKey, *rsa.PublicKey:
return true
}
return false
} Try / catch
if !isSupportedPublicKey(signer.Public()) {
return fmt.Errorf("cannot compute key ID for %T", signer.Public())
}
kid, err := keyID(signer.Public())
if err != nil { return err } Prevention
- Always pass signer.Public(), never the private key, to key ID computation.
- Standardize on ECDSA P-256 or RSA keys for CA/cert generation in this helper.
- Add a switch case for new key types when migrating (e.g. Ed25519 requires code changes here).
When it happens
Trigger: Calling keyID (directly, or indirectly via GenerateCA/GenerateCert with a custom signer) with an Ed25519 public key, ed25519.PrivateKey passed instead of its Public(), or any other crypto.Signer implementation.
Common situations: Forking or extending the CA code to use Ed25519 or a PKCS#11/HSM-backed signer; accidentally passing a private key rather than signer.Public(); refactoring so the wrong variable is handed to keyID.
Related errors
- common name value not provided
- country value not provided
- organization value not provided
- organizational unit value not provided
- certificate has expired or is not yet valid
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/413b905a6046c3f9.
Report an issue: GitHub.