gohugoio/hugo · error

failed to parse certificate: %v

Error message

failed to parse certificate: %v

What it means

After successfully PEM-decoding the cached TLS certificate, Hugo calls `x509.ParseCertificate` on the DER bytes. This error means the PEM block decoded but its payload is not a valid X.509 certificate — the block may be of the wrong type (e.g. a private key) or the DER data is corrupt.

Source

Thrown at commands/server.go:738

	// 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
}

func (c *serverCommand) createServerPorts(cd *simplecobra.Commandeer) error {
	flags := cd.CobraCommand.Flags()
	var cerr error
	c.withConf(func(conf *commonConfig) {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Delete `<hugo cacheDir>/_mkcerts/` and rerun `hugo server --tlsAuto` to regenerate the pair.
  2. If managing certs manually, confirm the cert file holds a `CERTIFICATE` block, not a key: `openssl x509 -in file.pem -noout -subject`.
  3. Ensure cert and key files weren't swapped (`<host>.pem` = cert, `<host>-key.pem` = key).
Defensive patterns

Strategy: validation

Validate before calling

block, _ := pem.Decode(certBytes)
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
    return fmt.Errorf("corrupt certificate: %w", err)
}

Prevention

When it happens

Trigger: `hugo server --tlsAuto` where `<cacheDir>/_mkcerts/<hostname>.pem` contains a PEM block whose bytes fail X.509 parsing — swapped cert/key files, a `PRIVATE KEY` block where the certificate should be, or bit-rot in the cached file.

Common situations: Accidentally copying the `-key.pem` content into the cert file; scripts that concatenate or rewrite cert files incorrectly; corrupted cache after crashes or sync conflicts.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/34560b93dc415987.json. Report an issue: GitHub ↗.