XTLS/Xray-core · error

failed to decode certificate

Error message

failed to decode certificate

What it means

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.

Source

Thrown at common/protocol/tls/cert/cert.go:30

	"encoding/pem"
	"math/big"
	"time"

	"github.com/xtls/xray-core/common"
	"github.com/xtls/xray-core/common/errors"
)

type Certificate struct {
	// certificate in ASN.1 DER format
	Certificate []byte
	// Private key in ASN.1 DER format
	PrivateKey []byte
}

func ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) {
	certBlock, _ := pem.Decode(certPEM)
	if certBlock == nil {
		return nil, errors.New("failed to decode certificate")
	}
	keyBlock, _ := pem.Decode(keyPEM)
	if keyBlock == nil {
		return nil, errors.New("failed to decode key")
	}
	return &Certificate{
		Certificate: certBlock.Bytes,
		PrivateKey:  keyBlock.Bytes,
	}, nil
}

func (c *Certificate) ToPEM() ([]byte, []byte) {
	return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.Certificate}),
		pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: c.PrivateKey})
}

type Option func(*x509.Certificate)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Confirm the first argument is the certificate PEM and the second is the key PEM (order matters)
  2. Convert DER to PEM with `openssl x509 -inform der -in cert.der -out cert.pem`
  3. Verify the file contains a CERTIFICATE PEM block: `openssl x509 -in file.pem -noout`

Example fix

// before
cert, err := cert.ParseCertificate(keyPEM, certPEM) // swapped

// after
cert, err := cert.ParseCertificate(certPEM, keyPEM)
Defensive patterns

Strategy: validation

Validate before calling

if !bytes.Contains(certPEM, []byte("-----BEGIN CERTIFICATE-----")) {
    return errors.New("certPEM has no CERTIFICATE block")
}

Type guard

func isPEMCertificate(b []byte) bool { block, _ := pem.Decode(b); return block != nil && block.Type == "CERTIFICATE" }

Prevention

When it happens

Trigger: Calling ParseCertificate with DER bytes, an empty certPEM, a key PEM passed as the cert, or PEM text corrupted (missing headers, bad line breaks).

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/287851baa345e754. Report an issue: GitHub.