hashicorp/nomad · error
no PEM-encoded data found
Error message
no PEM-encoded data found
What it means
caFileExpiry in command/agent/tls_metrics.go reads a CA certificate file for TLS expiry metrics and decodes the first PEM block. If pem.Decode finds no PEM data (block == nil), it returns this error, meaning the file is not PEM-encoded (or is empty/garbage) and certificate expiry cannot be computed.
Source
Thrown at command/agent/tls_metrics.go:144
metrics.SetGaugeWithLabels(
[]string{"agent", "tls", "ca", "expiration_seconds"},
float32(time.Until(t.caExpiry).Seconds()),
t.labels,
)
}
}
// certFileExpiry reads a PEM-encoded certificate file and returns the NotAfter
// time of the certificate.
func caFileExpiry(path string) (time.Time, error) {
data, err := os.ReadFile(path)
if err != nil {
return time.Time{}, fmt.Errorf("failed to read file: %w", err)
}
block, _ := pem.Decode(data)
if block == nil {
return time.Time{}, errors.New("no PEM-encoded data found")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return time.Time{}, fmt.Errorf("failed to parse certificate: %w", err)
}
return cert.NotAfter, nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the file contains a PEM-encoded certificate: it should start with `-----BEGIN CERTIFICATE-----`; convert DER to PEM with `openssl x509 -inform der -in ca.crt -out ca.pem`.
- Verify the file path in the agent TLS config points to the CA cert, not the key, directory, or an unrelated file.
- Check the file is non-empty and intact (`openssl x509 -in ca.pem -noout -subject`) and re-copy if corrupted.
- Confirm file permissions allow the Nomad agent user to read the file (though unreadable files usually surface as the read error instead).
Example fix
// before: DER binary cert ca_file = "/etc/ssl/ca.crt" // DER-encoded // after: convert to PEM // openssl x509 -inform der -in /etc/ssl/ca.crt -out /etc/ssl/ca.pem ca_file = "/etc/ssl/ca.pem"
Defensive patterns
Strategy: validation
Validate before calling
data, err := os.ReadFile(caFile)
if err != nil {
return err
}
if block, _ := pem.Decode(data); block == nil {
return fmt.Errorf("%s is not PEM-encoded; convert with: openssl x509 -inform der -in %s -out ca.pem", caFile, caFile)
} Type guard
func isPEMCertificate(data []byte) bool {
block, _ := pem.Decode(data)
return block != nil && block.Type == "CERTIFICATE"
} Try / catch
if _, err := tls.LoadX509KeyPair(certFile, keyFile); err != nil {
log.Printf("TLS files invalid: %v", err)
}
// at runtime:
if err != nil && strings.Contains(err.Error(), "no PEM-encoded data found") {
return fmt.Errorf("check ca_file %q: file is not PEM (DER or corrupt?)", caFile)
} Prevention
- Validate CA files with `openssl x509 -in ca.pem -noout` before deploying.
- Point ca_file at a PEM-encoded certificate, never a DER .crt, key file, or directory.
- Checksum certificates in config management to catch truncated downloads.
When it happens
Trigger: Configuring the agent's TLS CA file path (caFile) to a file that contains DER binary, an empty file, a private key format pem.Decode rejects, or plain text — then TLS metrics initialization (newTLSMetrics) invokes caFileExpiry.
Common situations: Pointing ca_file at a DER-encoded .crt (common from some CAs), at a directory or socket, at a bundle with only non-certificate PEM that pem.Decode can't parse, or a file truncated by a failed copy/download.
Related errors
- Failed to parse any valid certificates in CA file: %s
- unknown PEM block type for signing key: %s
- failed to parse root certificate
- failed to parse certificate
- failed to parse CA file: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/be382ed541a22e1a.
Report an issue: GitHub.