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

  1. Remove the passphrase: openssl rsa -in key.enc -out key.pem (or ec -in ... )
  2. Confirm the file has a PRIVATE KEY header, not PUBLIC KEY
  3. Re-copy the key preserving exact line breaks, or transfer via scp/base64 -d
  4. 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

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


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