AdguardTeam/AdGuardHome · error
tls: found unknown private key type %T in PKCS#8 wrapping
Error message
tls: found unknown private key type %T in PKCS#8 wrapping
What it means
A PKCS#8-wrapped private key parsed successfully but its algorithm is not RSA, ECDSA, or Ed25519 — the type switch in parsePrivateKey found an unexpected Go key type.
Source
Thrown at internal/aghtls/defaultmanager.go:937
// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
//
// TODO(a.garipov): Find out if this version of parsePrivateKey from the stdlib
// is actually necessary.
func parsePrivateKey(der []byte) (key crypto.PrivateKey, typ string, err error) {
if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
return key, keyTypeRSA, nil
}
if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
switch key := key.(type) {
case *rsa.PrivateKey:
return key, keyTypeRSA, nil
case *ecdsa.PrivateKey:
return key, keyTypeECDSA, nil
case ed25519.PrivateKey:
return key, keyTypeED25519, nil
default:
return nil, "", fmt.Errorf(
"tls: found unknown private key type %T in PKCS#8 wrapping",
key,
)
}
}
if key, err = x509.ParseECPrivateKey(der); err == nil {
return key, keyTypeECDSA, nil
}
return nil, "", errors.Error("tls: failed to parse private key")
}
View on GitHub (pinned to b41aefbe51)
Solutions
- Regenerate the key with a supported algorithm: RSA (>=2048), ECDSA (P-256), or standard tooling
- Inspect the key: openssl pkey -in key.pem -noout -text to identify the algorithm
- If Ed25519 was intended, note the library separately rejects it for browser-compatibility reasons; use ECDSA P-256 instead
Example fix
# before openssl dsaparam / genkey ... # unsupported # after openssl ecparam -name prime256v1 -genkey -out key.pem
Defensive patterns
Strategy: validation
Validate before calling
if k, err := x509.ParsePKCS8PrivateKey(der); err == nil {
switch k.(type) {
case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
default:
return fmt.Errorf("unsupported key algorithm %T", k)
}
} Type guard
func isSupportedKey(any any) bool {
switch any.(type) {
case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
return true
}
return false
} Try / catch
if err := mgr.LoadTLSConfig(ctx, conf); err != nil {
if strings.Contains(err.Error(), "unknown private key type") { /* regenerate with RSA/ECDSA */ }
} Prevention
- Generate keys only with mainstream algorithms (RSA-2048+, ECDSA P-256)
- Avoid DSA and exotic PKCS#8 algorithms for TLS keys
When it happens
Trigger: Extremely rare: a PKCS#8 structure carrying an unsupported algorithm OID (e.g., DSA, or an exotic/unknown algorithm) reaches x509.ParsePKCS8PrivateKey and yields a key type outside the supported set.
Common situations: Keys generated by nonstandard tooling emitting DSA or experimental algorithm OIDs in PKCS#8; corrupted-but-parsable key data producing an unexpected type.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- parsing private key: %w
- unknown cipher %q
- loading tls certificate: %w
- certificate-key pair: %w
- parsing tls certificate: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/48fd2d3d48d8ac22.
Report an issue: GitHub.