hashicorp/nomad · error
unknown PEM block type for signing key: %s
Error message
unknown PEM block type for signing key: %s
What it means
ParseSigner parses a PEM-encoded private key and returns a crypto.Signer. It supports RSA, EC, and PKCS#8 (Ed25519) PEM blocks; any other PEM block type reaches the default branch and this error is thrown, carrying the unrecognized block.Type header.
Source
Thrown at helper/tlsutil/generate.go:341
return x509.ParseECPrivateKey(block.Bytes)
case "RSA PRIVATE KEY":
return x509.ParsePKCS1PrivateKey(block.Bytes)
case "PRIVATE KEY":
signer, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
pk, ok := signer.(crypto.Signer)
if !ok {
return nil, fmt.Errorf("private key is not a valid format")
}
return pk, nil
default:
return nil, fmt.Errorf("unknown PEM block type for signing key: %s", block.Type)
}
}
func Verify(caString, certString, dns string) error {
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(caString))
if !ok {
return fmt.Errorf("failed to parse root certificate")
}
cert, err := parseCert(certString)
if err != nil {
return fmt.Errorf("failed to parse certificate")
}
opts := x509.VerifyOptions{
DNSName: fmt.Sprint(dns),
Roots: roots,View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect block.Type with pem.Decode on the file and confirm it contains the intended private key, not the certificate
- Regenerate or export the key as PKCS#8 ('BEGIN PRIVATE KEY') or the matching RSA/EC private-key PEM format
- If the file holds a cert+key bundle, split out only the private-key section before parsing
Example fix
// before signer, err := tlsutil.ParseSigner(certPEM) // cert block, not key // after signer, err := tlsutil.ParseSigner(keyPEM) // block type: RSA/EC PRIVATE KEY or PRIVATE KEY
Defensive patterns
Strategy: validation
Validate before calling
block, _ := pem.Decode(keyPEM)
if block == nil {
return fmt.Errorf("no PEM data found")
}
switch block.Type {
case "RSA PRIVATE KEY", "EC PRIVATE KEY", "PRIVATE KEY":
// ok
default:
return fmt.Errorf("unsupported key block type %q", block.Type)
}
signer, err := tlsutil.ParseSigner(keyPEM) Type guard
func isPrivateKeyPEM(pemBytes []byte) bool {
block, _ := pem.Decode(pemBytes)
return block != nil && (block.Type == "RSA PRIVATE KEY" || block.Type == "EC PRIVATE KEY" || block.Type == "PRIVATE KEY")
} Try / catch
signer, err := tlsutil.ParseSigner(keyPEM)
if err != nil {
if strings.HasPrefix(err.Error(), "unknown PEM block type") {
return fmt.Errorf("key file is not a supported private key PEM (check cert vs key): %w", err)
}
return err
} Prevention
- Keep certificate and key files separate; never feed a combined bundle to ParseSigner
- Check the PEM BEGIN line before parsing to confirm it is a private key
- Standardize on PKCS#8 ('BEGIN PRIVATE KEY') key encoding
- Reject encrypted password-protected keys at config load time
When it happens
Trigger: Calling ParseSigner (directly or via newCert/Run/IsValidSigner in tlsutil) with PEM data whose block type is not 'RSA PRIVATE KEY', 'EC PRIVATE KEY', or 'PRIVATE KEY' — e.g. a public key, certificate, or encrypted key block passed where a private key is expected.
Common situations: Pointing a CA/leaf key config at the certificate file instead of the key file; passing an encrypted 'ENCRYPTED PRIVATE KEY' or legacy format; concatenating cert+key in one file and feeding the whole bundle to ParseSigner.
Related errors
- no PEM-encoded data found
- Failed to parse any valid certificates in CA file: %s
- failed to parse root certificate
- failed to parse certificate
- failed to parse cert key pair: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/a8d940d600cb4117.
Report an issue: GitHub.