{"record":{"id":"287851baa345e754","repo":"XTLS/Xray-core","slug":"failed-to-decode-certificate","errorCode":null,"errorMessage":"failed to decode certificate","messagePattern":"failed to decode certificate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/protocol/tls/cert/cert.go","lineNumber":30,"sourceCode":"\t\"encoding/pem\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/xtls/xray-core/common\"\n\t\"github.com/xtls/xray-core/common/errors\"\n)\n\ntype Certificate struct {\n\t// certificate in ASN.1 DER format\n\tCertificate []byte\n\t// Private key in ASN.1 DER format\n\tPrivateKey []byte\n}\n\nfunc ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) {\n\tcertBlock, _ := pem.Decode(certPEM)\n\tif certBlock == nil {\n\t\treturn nil, errors.New(\"failed to decode certificate\")\n\t}\n\tkeyBlock, _ := pem.Decode(keyPEM)\n\tif keyBlock == nil {\n\t\treturn nil, errors.New(\"failed to decode key\")\n\t}\n\treturn &Certificate{\n\t\tCertificate: certBlock.Bytes,\n\t\tPrivateKey:  keyBlock.Bytes,\n\t}, nil\n}\n\nfunc (c *Certificate) ToPEM() ([]byte, []byte) {\n\treturn pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: c.Certificate}),\n\t\tpem.EncodeToMemory(&pem.Block{Type: \"RSA PRIVATE KEY\", Bytes: c.PrivateKey})\n}\n\ntype Option func(*x509.Certificate)\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/protocol/tls/cert/cert.go#L12-L48","documentation":"Returned by ParseCertificate when pem.Decode finds no PEM block in the certificate input. The expected '-----BEGIN CERTIFICATE-----' envelope is absent, so there is nothing to extract DER bytes from.","triggerScenarios":"Calling ParseCertificate with DER bytes, an empty certPEM, a key PEM passed as the cert, or PEM text corrupted (missing headers, bad line breaks).","commonSituations":"Config loading cert/key files in the wrong order (key file given as certPEM), base64 that got mangled, or DER-format files supplied where PEM is required.","solutions":["Confirm the first argument is the certificate PEM and the second is the key PEM (order matters)","Convert DER to PEM with `openssl x509 -inform der -in cert.der -out cert.pem`","Verify the file contains a CERTIFICATE PEM block: `openssl x509 -in file.pem -noout`"],"exampleFix":"// before\ncert, err := cert.ParseCertificate(keyPEM, certPEM) // swapped\n\n// after\ncert, err := cert.ParseCertificate(certPEM, keyPEM)","handlingStrategy":"validation","validationCode":"if !bytes.Contains(certPEM, []byte(\"-----BEGIN CERTIFICATE-----\")) {\n    return errors.New(\"certPEM has no CERTIFICATE block\")\n}","typeGuard":"func isPEMCertificate(b []byte) bool { block, _ := pem.Decode(b); return block != nil && block.Type == \"CERTIFICATE\" }","tryCatchPattern":null,"preventionTips":["Smoke-test PEM files with openssl before deploying","Pass (cert, key) in the documented order"],"tags":["tls","certificate","pem","parsing"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}