{"record":{"id":"9ec8476f3da16f23","repo":"goharbor/harbor","slug":"invalid-ca-certificate-no-valid-certificates-foun","errorCode":null,"errorMessage":"invalid CA certificate: no valid certificates found in PEM data","messagePattern":"invalid CA certificate: no valid certificates found in PEM data","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"src/common/http/transport.go","lineNumber":125,"sourceCode":"\treturn cert\n}\n\n// ValidateCACertificate validates whether the provided CA certificate string\n// contains at least one valid PEM-encoded x509 certificate.\nfunc ValidateCACertificate(caCert string) error {\n\tcaCert = normalizePEM(caCert)\n\tif caCert == \"\" {\n\t\treturn nil\n\t}\n\n\t// Attempt to parse one or more certificates from the provided PEM\n\tcerts, err := parseCertificatesFromPEM(caCert)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid CA certificate: %w\", err)\n\t}\n\n\tif len(certs) == 0 {\n\t\treturn errors.New(\"invalid CA certificate: no valid certificates found in PEM data\")\n\t}\n\n\treturn nil\n}\n\n// parseCertificatesFromPEM decodes all PEM blocks and parses certificates.\nfunc parseCertificatesFromPEM(pemData string) ([]*x509.Certificate, error) {\n\tvar certs []*x509.Certificate\n\trest := []byte(pemData)\n\n\tfor {\n\t\tvar block *pem.Block\n\t\tblock, rest = pem.Decode(rest)\n\t\tif block == nil {\n\t\t\tbreak\n\t\t}\n\t\tif block.Type != \"CERTIFICATE\" {\n\t\t\tcontinue","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/common/http/transport.go#L107-L143","documentation":"ValidateCACertificate in Harbor's common HTTP transport rejects a non-empty CA certificate string from which no valid x509 certificate could be parsed. normalizePEM first trims whitespace and normalizes line endings, then pem.Decode must find at least one block of type CERTIFICATE that x509.ParseCertificate accepts; zero parseable certificates triggers this error. Empty input is allowed (returns nil).","triggerScenarios":"Supplying a CA certificate that is DER (binary), a private key or CSR only, an OpenSSL 'TRUSTED CERTIFICATE' block, a PEM with mangled BEGIN/END headers, base64 garbage, or only non-CERTIFICATE PEM blocks (e.g. just the key pair's PRIVATE KEY block).","commonSituations":"Copy-pasting the wrong half of a keypair into a registry or replication endpoint CA field, Windows line-ending or truncated pastes, certificates exported as DER from Windows certmgr.","solutions":["Verify the PEM locally: openssl x509 -in ca.crt -noout -text — if that fails, the PEM is bad","Convert DER to PEM: openssl x509 -inform der -in ca.der -out ca.pem","Strip the TRUSTED marker: openssl x509 -in trusted.crt -out plain.crt","Ensure the block reads -----BEGIN CERTIFICATE----- / -----END CERTIFICATE----- with intact base64, and paste only certificate(s), never a private key"],"exampleFix":"# before: DER file pasted as 'CA certificate'\nopenssl x509 -inform der -in ca.der -out ca.pem   # convert DER -> PEM\nopenssl x509 -in ca.pem -noout -text              # must print cert details\n# after: paste ca.pem's BEGIN/END CERTIFICATE block into the CA field","handlingStrategy":"validation","validationCode":"// verify a CA PEM the same way Harbor does, before configuring it\nfunc hasValidCertPEM(pemStr string) bool {\n    rest := []byte(strings.TrimSpace(pemStr))\n    found := false\n    for {\n        var block *pem.Block\n        block, rest = pem.Decode(rest)\n        if block == nil {\n            return found\n        }\n        if block.Type == \"CERTIFICATE\" {\n            if _, err := x509.ParseCertificate(block.Bytes); err != nil {\n                return false\n            }\n            found = true\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always validate with openssl x509 -in ca.crt -noout -text before pasting a CA","Export PEM, not DER, from certificate managers","Never paste the PRIVATE KEY block into a CA certificate field"],"tags":["go","tls","pem","certificate","harbor","x509"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}