gohugoio/hugo · error
failed to parse certificate PEM
Error message
failed to parse certificate PEM
What it means
During `--tlsAuto` cert reuse, Hugo PEM-decodes the cached server certificate (`<cacheDir>/_mkcerts/<host>.pem`) before x509 parsing. `pem.Decode` returned nil, meaning the file contains no PEM block at all — it's empty, truncated, or not PEM-encoded.
Source
Thrown at commands/server.go:734
}
c.r.Println("Creating TLS certificates in", keyDir)
// Yes, this is unfortunate, but it's currently the only way to use Mkcert as a library.
os.Args = []string{"-cert-file", c.tlsCertFile, "-key-file", c.tlsKeyFile, hostname}
return mclib.RunMain()
}
func (c *serverCommand) verifyCert(rootPEM, certPEM []byte, name string) error {
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM(rootPEM)
if !ok {
return fmt.Errorf("failed to parse root certificate")
}
block, _ := pem.Decode(certPEM)
if block == nil {
return fmt.Errorf("failed to parse certificate PEM")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return fmt.Errorf("failed to parse certificate: %v", err.Error())
}
opts := x509.VerifyOptions{
DNSName: name,
Roots: roots,
}
if _, err := cert.Verify(opts); err != nil {
return fmt.Errorf("failed to verify certificate: %v", err.Error())
}
return nil
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Delete the cached certificates (`<hugo cacheDir>/_mkcerts/`) and rerun `hugo server --tlsAuto` so fresh certs are generated.
- If supplying your own certs via `--tlsCertFile`/`--tlsKeyFile`, ensure they are PEM-encoded (convert DER with `openssl x509 -inform der -in cert.der -out cert.pem`).
- Verify the file isn't empty: `openssl x509 -in <host>.pem -noout` should parse.
Defensive patterns
Strategy: validation
Validate before calling
block, _ := pem.Decode(certBytes)
if block == nil || block.Type != "CERTIFICATE" {
return errors.New("cert file is not a PEM CERTIFICATE block")
} Prevention
- Ensure the file starts with -----BEGIN CERTIFICATE-----
- Don't pass DER-encoded or key files where a PEM cert is expected
- Keep cert and key in separate, correctly named files
When it happens
Trigger: `hugo server --tlsAuto` reading a cached `<hostname>.pem` whose contents lack a `-----BEGIN CERTIFICATE-----` block; note verifyCert is called only when both the cached cert and the mkcert rootCA were readable.
Common situations: Interrupted certificate generation leaving a zero-byte or partial file in `_mkcerts`; disk-full during write; manually replacing the cert with a DER/pkcs12 file; sync tools mangling line endings or content of the cache dir.
Related errors
- failed to parse root certificate
- failed to parse certificate: %v
- failed to verify certificate: %v
- cannot use --renderToMemory with --destination
- failed to create baseURL from %q: %s
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/db63f25d3a36cc54.json.
Report an issue: GitHub ↗.