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

  1. Regenerate the key with a supported algorithm: RSA (>=2048), ECDSA (P-256), or standard tooling
  2. Inspect the key: openssl pkey -in key.pem -noout -text to identify the algorithm
  3. 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

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

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/48fd2d3d48d8ac22. Report an issue: GitHub.