hashicorp/nomad · error

no PEM-encoded data found

Error message

no PEM-encoded data found

What it means

The public ParseCert could not find any PEM block in the provided string: pem.Decode returned nil. The input is empty, whitespace, or not PEM-formatted at all, so no certificate can be parsed from it.

Source

Thrown at helper/tlsutil/generate.go:288

	// This is not standard; RFC allows any unique identifier as long as they
	// match in subject/authority chains but suggests specific hashing of DER
	// bytes of public key including DER tags.
	bs, err := x509.MarshalPKIXPublicKey(raw)
	if err != nil {
		return nil, err
	}

	// String formatted
	kID := sha256.Sum256(bs)
	return kID[:], nil
}

// ParseCert parses the x509 certificate from a PEM-encoded value.
func ParseCert(pemValue string) (*x509.Certificate, error) {
	// The _ result below is not an error but the remaining PEM bytes.
	block, _ := pem.Decode([]byte(pemValue))
	if block == nil {
		return nil, fmt.Errorf("no PEM-encoded data found")
	}

	if block.Type != "CERTIFICATE" {
		return nil, fmt.Errorf("first PEM-block should be CERTIFICATE type")
	}

	return x509.ParseCertificate(block.Bytes)
}

func parseCert(pemValue string) (*x509.Certificate, error) {
	// The _ result below is not an error but the remaining PEM bytes.
	block, _ := pem.Decode([]byte(pemValue))
	if block == nil {
		return nil, fmt.Errorf("no PEM-encoded data found")
	}

	if block.Type != "CERTIFICATE" {
		return nil, fmt.Errorf("first PEM-block should be CERTIFICATE type")

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the input actually contains a PEM block starting with -----BEGIN CERTIFICATE----- and ending with -----END CERTIFICATE-----.
  2. Read the certificate file's contents, not its path, before calling ParseCert.
  3. Check the config/KV source for empty or truncated values.
  4. If you have raw DER, wrap it with pem.EncodeToMemory yourself or use x509.ParseCertificate directly.

Example fix

// before
parsed, err := tlsutil.ParseCert(certPath)
// after
certPEM, err := os.ReadFile(certPath)
if err != nil { return err }
parsed, err := tlsutil.ParseCert(string(certPEM))
Defensive patterns

Strategy: validation

Validate before calling

func hasCertPEM(s string) bool {
	block, _ := pem.Decode([]byte(s))
	return block != nil && block.Type == "CERTIFICATE"
}

Type guard

func isPEMCertificate(s string) bool {
	block, _ := pem.Decode([]byte(s))
	return block != nil && block.Type == "CERTIFICATE"
}

Try / catch

cert, err := tlsutil.ParseCert(pemValue)
if err != nil {
	if strings.Contains(err.Error(), "no PEM-encoded data found") {
		return fmt.Errorf("certificate input is empty or not PEM-encoded: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling ParseCert("") or ParseCert with raw DER bytes (no -----BEGIN CERTIFICATE----- armor), base64-without-PEM output, truncated PEM missing the BEGIN line, or config fields that were never populated.

Common situations: Reading a cert from a config value or Consul KV key that is empty; passing a file path instead of file contents; stripping PEM headers during preprocessing; Windows line-ending or encoding corruption that breaks the BEGIN/END markers.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/725f60b0594c006f. Report an issue: GitHub.