{"record":{"id":"34560b93dc415987","repo":"gohugoio/hugo","slug":"failed-to-parse-certificate-v","errorCode":null,"errorMessage":"failed to parse certificate: %v","messagePattern":"failed to parse certificate: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"commands/server.go","lineNumber":738,"sourceCode":"\t// Yes, this is unfortunate, but it's currently the only way to use Mkcert as a library.\n\tos.Args = []string{\"-cert-file\", c.tlsCertFile, \"-key-file\", c.tlsKeyFile, hostname}\n\treturn mclib.RunMain()\n}\n\nfunc (c *serverCommand) verifyCert(rootPEM, certPEM []byte, name string) error {\n\troots := x509.NewCertPool()\n\tok := roots.AppendCertsFromPEM(rootPEM)\n\tif !ok {\n\t\treturn fmt.Errorf(\"failed to parse root certificate\")\n\t}\n\n\tblock, _ := pem.Decode(certPEM)\n\tif block == nil {\n\t\treturn fmt.Errorf(\"failed to parse certificate PEM\")\n\t}\n\tcert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse certificate: %v\", err.Error())\n\t}\n\n\topts := x509.VerifyOptions{\n\t\tDNSName: name,\n\t\tRoots:   roots,\n\t}\n\n\tif _, err := cert.Verify(opts); err != nil {\n\t\treturn fmt.Errorf(\"failed to verify certificate: %v\", err.Error())\n\t}\n\n\treturn nil\n}\n\nfunc (c *serverCommand) createServerPorts(cd *simplecobra.Commandeer) error {\n\tflags := cd.CobraCommand.Flags()\n\tvar cerr error\n\tc.withConf(func(conf *commonConfig) {","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/commands/server.go#L720-L756","documentation":"After a PEM block is decoded, `verifyCert` calls `x509.ParseCertificate(block.Bytes)` to turn the DER bytes into a certificate. This wraps an ASN.1/x509 parse failure, meaning the PEM looked valid but the certificate bytes are malformed. `%v` is the x509 error string.","triggerScenarios":"Fires when the decoded PEM block is a certificate block (`CERTIFICATE`) but its DER bytes fail x509 parsing — truncated, corrupted, or not actually an X.509 cert despite the header.","commonSituations":"A `.pem` file that wraps a CSR or a non-cert block under a CERTIFICATE header; byte-level corruption from a bad download/copy; a PEM produced by a broken cert tool.","solutions":["Re-verify the certificate with `openssl x509 -in cert.pem -noout -text` to reproduce the parse error.","Delete the cached `_mkcerts` cert and regenerate via mkcert or Hugo's `--tlsAuto`.","Re-fetch the certificate from its original issuer if supplied externally."],"exampleFix":"// before\n// $ openssl x509 -in _mkcerts/localhost.pem -noout -text  -> unable to load certificate\n// after\n// rm _mkcerts/localhost*.pem && mkcert localhost","handlingStrategy":"validation","validationCode":"import (\n  \"crypto/x509\"\n  \"encoding/pem\"\n)\nfunc validateCert(path string) error {\n  b, err := os.ReadFile(path)\n  if err != nil { return err }\n  block, _ := pem.Decode(b)\n  if block == nil { return fmt.Errorf(\"no PEM block\") }\n  if _, err := x509.ParseCertificate(block.Bytes); err != nil { return err }\n  return nil\n}","typeGuard":"null","tryCatchPattern":"// On parse failure, discard the cached cert and let mkcert reissue.\nif _, err := x509.ParseCertificate(block.Bytes); err != nil {\n  os.Remove(certFile); os.Remove(keyFile)\n  // re-provision on next run\n}","preventionTips":["Cross-check certs with openssl before relying on them.","Regenerate cached certs from a known-good source when they fail to parse.","Avoid hand-editing cert files."],"tags":["hugo","server","tls","x509","certificate"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}