{"record":{"id":"ca628893a4ce04d8","repo":"coollabsio/coolify","slug":"invalid-certificate-format","errorCode":null,"errorMessage":"Invalid certificate format.","messagePattern":"Invalid certificate format\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Livewire/Server/CaCertificate/Show.php","lineNumber":65,"sourceCode":"        }\n    }\n\n    public function toggleCertificate()\n    {\n        $this->showCertificate = ! $this->showCertificate;\n    }\n\n    public function saveCaCertificate()\n    {\n        try {\n            $this->authorize('manageCaCertificate', $this->server);\n            if (! $this->certificateContent) {\n                throw new \\Exception('Certificate content cannot be empty.');\n            }\n\n            $parsedCert = openssl_x509_read($this->certificateContent);\n            if (! $parsedCert) {\n                throw new \\Exception('Invalid certificate format.');\n            }\n\n            if (! openssl_x509_export($parsedCert, $cleanedCertificate)) {\n                throw new \\Exception('Failed to process certificate.');\n            }\n            $this->certificateContent = $cleanedCertificate;\n\n            if ($this->caCertificate) {\n                $this->caCertificate->ssl_certificate = $this->certificateContent;\n                $this->caCertificate->save();\n\n                $this->loadCaCertificate();\n\n                $this->writeCertificateToServer();\n\n                dispatch(new RegenerateSslCertJob(\n                    server_id: $this->server->id,\n                    force_regeneration: true","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Livewire/Server/CaCertificate/Show.php#L47-L83","documentation":"openssl_x509_read() on the submitted PEM returned false, meaning PHP's OpenSSL could not parse certificateContent as an X.509 certificate. Coolify uses this both to validate and to normalize (re-export) the certificate before storing it on the server, so garbage input is refused before any write. Note openssl_x509_read emits a warning and returns false rather than throwing.","triggerScenarios":"Pasting a private key (-----BEGIN PRIVATE KEY-----) or a CSR instead of the certificate; missing BEGIN/END CERTIFICATE PEM headers; truncated or line-wrapped-mangled base64; DER/binary content; concatenated 'cert + chain + key' blobs where parsing of the first block fails.","commonSituations":"Grabbing the wrong file from the cert bundle; copy-paste losing line breaks; certificates from tools that emit PKCS#7 or DER; Windows line-ending mangles (rare - OpenSSL usually tolerates CRLF).","solutions":["Paste exactly the leaf/CA certificate PEM block: -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----","Verify locally: openssl x509 -in cert.pem -noout -subject (errors mean the file is not a cert)","If you have DER, convert first: openssl x509 -inform der -in cert.der -out cert.pem","Ensure line breaks survived copy-paste (each base64 line ~64 chars, single trailing newline)"],"exampleFix":"// before\n$this->certificateContent = \"-----BEGIN PRIVATE KEY-----\\nMIIEvQ...\\n-----END PRIVATE KEY-----\\n\";\n\n// after\n$this->certificateContent = \"-----BEGIN CERTIFICATE-----\\nMIIDdzCCAl+gAwIBAgIE...\\n-----END CERTIFICATE-----\\n\";","handlingStrategy":"validation","validationCode":"// pre-parse before saving\n$parsed = @openssl_x509_read($certificateContent);\nif ($parsed === false) {\n    // reject before saveCaCertificate; check openssl_error_string() for detail\n}\nopenssl_x509_free($parsed);","typeGuard":"/** @param mixed $content */\nfunction isParsableCertificate($content): bool\n{\n    if (! is_string($content) || $content === '') {\n        return false;\n    }\n    $res = @openssl_x509_read($content);\n    if ($res !== false) { openssl_x509_free($res); }\n\n    return $res !== false;\n}","tryCatchPattern":"Silence and inspect warnings with @openssl_x509_read(...) === false plus openssl_error_string(); throw/log a clear message - the function returns false rather than throwing, so a bare try/catch will not catch it.","preventionTips":["Verify locally with openssl x509 -in cert.pem -noout before pasting","Paste certificates, never keys or CSRs - check the BEGIN header line","Convert DER/PKCS#7 to PEM before importing"],"tags":["certificate","openssl","x509","pem","validation"],"backgroundTag":"x509-certificate-parse-failed","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}