AdguardTeam/AdGuardHome · error
parsing private key: %w
Error message
parsing private key: %w
What it means
The PEM private key block could not be parsed into a known key format by parsePrivateKey. The wrapped error indicates the key bytes are corrupt, truncated, encrypted in an unsupported way, or not a valid PKCS#1/PKCS#8/EC key.
Source
Thrown at internal/aghtls/defaultmanager.go:797
// Go through all pem blocks, but take first valid pem block and drop the
// rest.
for decoded, pemblock := pem.Decode([]byte(pkey)); decoded != nil; {
if decoded.Type == "PRIVATE KEY" || strings.HasSuffix(decoded.Type, " PRIVATE KEY") {
key = decoded
break
}
decoded, pemblock = pem.Decode(pemblock)
}
if key == nil {
return "", errors.Error("no valid keys were found")
}
_, keyType, err = parsePrivateKey(key.Bytes)
if err != nil {
return "", fmt.Errorf("parsing private key: %w", err)
}
if keyType == keyTypeED25519 {
return "", errors.Error(
"ED25519 keys are not supported by browsers; " +
"did you mean to use X25519 for key exchange?",
)
}
return keyType, nil
}
// validateCertificates processes certificate data and its private key. status
// must not be nil, since it's used to accumulate the validation results.
// logger and tlsManager must not be nil. Other parameters are optional.
func validateCertificates(
ctx context.Context,
logger *slog.Logger,View on GitHub (pinned to b41aefbe51)
Solutions
- Remove the passphrase: openssl rsa -in key.enc -out key.pem (or ec -in ... )
- Confirm the file has a PRIVATE KEY header, not PUBLIC KEY
- Re-copy the key preserving exact line breaks, or transfer via scp/base64 -d
- Verify offline: openssl pkey -in key.pem -noout
Example fix
# before openssl genrsa -aes256 ... # encrypted key # after openssl rsa -in encrypted.key -out plain.key
Defensive patterns
Strategy: validation
Validate before calling
block, _ := pem.Decode(keyPEM)
if block == nil || !strings.Contains(block.Type, "PRIVATE KEY") {
return fmt.Errorf("not a private key PEM")
}
if _, _, err := parsePrivateKey(block.Bytes); err != nil { return err } Try / catch
if err := mgr.LoadTLSConfig(ctx, conf); err != nil {
if strings.Contains(err.Error(), "parsing private key") { /* decrypt or replace the key */ }
} Prevention
- Use unencrypted (no passphrase) keys for server TLS in Go
- Validate keys with openssl pkey before deployment
- Avoid Ed25519 keys for browser-facing TLS (explicitly rejected upstream)
When it happens
Trigger: validatePKey runs during LoadTLSConfig; triggers when PrivateKeyData contains a PEM block whose DER payload fails parsing: wrong PEM type, encrypted (passphrase-protected) key, or corrupt base64/DER.
Common situations: Using a passphrase-protected key (Go's tls package does not decrypt them); pasting a public key instead of the private key; line-wrapping damage from copying the key through email/docs.
Related errors
- tls: found unknown private key type %T in PKCS#8 wrapping
- unknown cipher %q
- loading tls certificate: %w
- parsing certificate at index %d: %w
- certificate-key pair: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/98095ba1c33616d7.
Report an issue: GitHub.