caddyserver/caddy · error
unsupported key type: %T
Error message
unsupported key type: %T
What it means
Returned by verifyKeysMatch (modules/caddypki/crypto.go:154) when the public key embedded in the certificate being loaded is not RSA, ECDSA, or Ed25519. Caddy's PKI only knows how to verify these three key families, so any other algorithm in the cert's SubjectPublicKeyInfo fails here at the default switch case.
Source
Thrown at modules/caddypki/crypto.go:154
}
case *ecdsa.PublicKey:
pk, ok := signer.Public().(*ecdsa.PublicKey)
if !ok {
return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub)
}
if !pub.Equal(pk) {
return errors.New("private key does not match issuer public key")
}
case ed25519.PublicKey:
pk, ok := signer.Public().(ed25519.PublicKey)
if !ok {
return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub)
}
if !pub.Equal(pk) {
return errors.New("private key does not match issuer public key")
}
default:
return fmt.Errorf("unsupported key type: %T", pub)
}
return nil
}
View on GitHub (pinned to 50e54ee279)
Solutions
- Re-issue the CA certificate with a supported key algorithm: RSA (>=2048), ECDSA (P-256/P-384/P-521), or Ed25519
- Check the algorithm before importing: openssl x509 -in cert.pem -noout -text | grep 'Public Key Algorithm'
- If you must keep the external CA, terminate its certificates in the TLS app instead of loading it as a Caddy PKI root/intermediate
Example fix
# before: DSA root openssl dsaparam -genkey 2048 > d.key && openssl req -x509 -new -key d.key ... # after: ECDSA root openssl ecparam -name prime256v1 -genkey -noout -out key.pem openssl req -x509 -new -key key.pem -subj '/CN=My Root' -days 3650 -out root.crt
Defensive patterns
Strategy: validation
Validate before calling
// reject unsupported algorithms before handing certs to Caddy
func isSupportedCertAlgorithm(certFile string) (bool, error) {
out, err := exec.Command("openssl", "x509", "-in", certFile, "-noout", "-text").Output()
if err != nil {
return false, err
}
txt := string(out)
return strings.Contains(txt, "rsaEncryption") ||
strings.Contains(txt, "id-ecPublicKey") ||
strings.Contains(txt, "ED25519"), nil
} Type guard
// Go-side guard using the parsed certificate
func certUsesSupportedKey(crt *x509.Certificate) bool {
switch crt.PublicKey.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
return true
}
return false
} Try / catch
if err := ca.Provision(ctx, caID, p.log); err != nil {
if strings.Contains(err.Error(), "unsupported key type") {
// algorithm-level problem: re-issue the CA cert with RSA/ECDSA/Ed25519
}
return err
} Prevention
- Standardize your PKI on P-256 ECDSA or RSA-2048; both are universally supported by Caddy
- When importing third-party CA certs, check the key algorithm with openssl before adding them to Caddy's pki config
- Keep DSA/Ed448/PQC keys out of CA certificates used by Caddy's internal PKI
When it happens
Trigger: Supplying a CA root or intermediate certificate whose public key uses an unsupported algorithm (e.g. DSA, Ed448, or an ECDH-typed key) via the root/intermediate cert_file/key_file config. The error fires during provisioning when the chain is read and verifyKeysMatch is called with the loaded certificate and signer.
Common situations: Importing certificates from legacy or exotic CAs that still use DSA; keys generated by experimental tooling (Ed448, Dilithium/PQC pilots); OpenSSL-generated ECDH keys mistakenly used where an ECDSA signing key was required.
Related errors
- generating root: %v
- decoding root key: %v
- generating CA root: %v
- generating new intermediate cert: %v
- decoding intermediate key: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/6e1c7def5b666e44.
Report an issue: GitHub.