{"record":{"id":"35593123b76efa74","repo":"firecrawl/firecrawl","slug":"scrape-ssl-error-355931","errorCode":"SCRAPE_SSL_ERROR","errorMessage":"An SSL/TLS certificate error occurred while trying to establish a secure connection to this website. This usually happens when a website has an expired, self-signed, or misconfigured SSL certificate. If you trust this website and are not submitting sensitive data, you can bypass this error by setting `skipTlsVerification: true` in your scrape request. Note: Only do this for trusted sites as it disables certificate validation.","messagePattern":"An SSL/TLS certificate error occurred while trying to establish a secure connection to this website\\. This usually happens when a website has an expired, self-signed, or misconfigured SSL certificate\\. If you trust this website and are not submitting sensitive data, you can bypass this error by setting `skipTlsVerification: true` in your scrape request\\. Note: Only do this for trusted sites as it disables certificate validation\\.","errorType":"error_code","errorClass":"SSLError","httpStatus":500,"severity":"error","filePath":"apps/api/src/scraper/scrapeURL/engines/fire-engine/checkStatus.ts","lineNumber":220,"sourceCode":"    ) {\n      logger.info(\n        \"Scrape job signaled retryWithStealth. Adding stealthProxy flag.\",\n        { jobId },\n      );\n      throw new AddFeatureError([\"stealthProxy\"]);\n    }\n    if (\n      typeof status.error === \"string\" &&\n      status.error.includes(\"Chrome error: \")\n    ) {\n      const code = status.error.split(\"Chrome error: \")[1];\n\n      if (\n        code.includes(\"ERR_CERT_\") ||\n        code.includes(\"ERR_SSL_\") ||\n        code.includes(\"ERR_BAD_SSL_\")\n      ) {\n        throw new SSLError(meta.options.skipTlsVerification);\n      } else {\n        throw new SiteError(code);\n      }\n    } else if (\n      typeof status.error === \"string\" &&\n      status.error.includes(\"proxies available for\")\n    ) {\n      throw new ProxySelectionError();\n    } else if (\n      typeof status.error === \"string\" &&\n      status.error.includes(\"Dns resolution error for hostname: \")\n    ) {\n      throw new DNSResolutionError(\n        status.error.split(\"Dns resolution error for hostname: \")[1],\n      );\n    } else if (\n      typeof status.error === \"string\" &&\n      status.error.includes(\"File exceeds size limit\")","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/firecrawl/firecrawl/blob/656bffcc2883f1af5befe38766b1ff5f0469993a/apps/api/src/scraper/scrapeURL/engines/fire-engine/checkStatus.ts#L202-L238","documentation":"SSLError from fire-engine checkStatus: the job's status.error string contains 'Chrome error: ' and the extracted code includes ERR_CERT_, ERR_SSL_, or ERR_BAD_SSL_. This is the CDP/browser path reporting a TLS failure while loading the page. The thrown SSLError carries meta.options.skipTlsVerification so the caller can be told how to bypass.","triggerScenarios":"A Chrome/CDP scrape (fire-engine checkStatus) whose page load fails with a Chrome network error in the certificate family. status.error looks like 'Chrome error: ERR_CERT_AUTHORITY_INVALID' or 'ERR_SSL_PROTOCOL_ERROR'; the substring checks at checkStatus.ts:214-217 match and throw SSLError.","commonSituations":"Self-signed internal sites; sites with expired/misconfigured certs; corporate proxies doing TLS interception; staging environments; sites that only present a valid cert to specific SNI values. Happens specifically on the browser path, distinct from the fetch-engine CERT_HAS_EXPIRED case.","solutions":["Set skipTlsVerification: true in the scrape request for trusted sites.","Try the http:// variant of the URL if available.","Have the site operator fix the certificate (renew/rechain/fix SNI).","If behind a corporate TLS-intercepting proxy, exempt Firecrawl or scrape from a non-intercepting network."],"exampleFix":"// before\nawait scrapeURL({ url: 'https://self-signed.internal.example.com', engine: 'fire-engine' });\n\n// after\nawait scrapeURL({ url: 'https://self-signed.internal.example.com', engine: 'fire-engine', skipTlsVerification: true });","handlingStrategy":"retry","validationCode":"async function certLooksValid(url) {\n  try { await fetch(url, { method: 'HEAD' }); return true; }\n  catch (e) { return !(e?.cause?.code?.startsWith('ERR_CERT_') || e?.cause?.code?.startsWith('ERR_SSL_')); }\n}","typeGuard":"import { SSLError } from '../error';\nfunction isSSLError(e) {\n  return e instanceof SSLError || (e instanceof Error && e.name === 'SSLError');\n}","tryCatchPattern":"try {\n  await scrapeURL({ url, engine: 'fire-engine' });\n} catch (e) {\n  if (isSSLError(e) && isTrustedInternal(url)) {\n    await scrapeURL({ url, engine: 'fire-engine', skipTlsVerification: true });\n  } else throw e;\n}","preventionTips":["Maintain a trusted-host safelist for skipTlsVerification.","Use http:// for internal services that do not need TLS.","Watch cert expiry across the targets you scrape and renew proactively."],"tags":["scraper","fire-engine","tls","ssl","certificate","chrome","cdp","network","firecrawl"],"analyzedSha":"656bffcc2883f1af5befe38766b1ff5f0469993a","analyzedAt":"2026-08-12T01:18:00.488Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}