unclecode/crawl4ai · error · ConnectionError
Connection failed: {str(e)}
Error message
Connection failed: {str(e)} What it means
Raised when aiohttp raises ClientConnectorError, meaning the TCP/TLS connection could never be established: DNS resolution failure, refused connection, unreachable host, or TLS handshake failure. The HTTP crawler wraps it into a plain ConnectionError with the underlying cause text.
Source
Thrown at crawl4ai/async_crawler_strategy.py:2784
result = AsyncCrawlResponse(
html=html,
response_headers=response_headers,
status_code=response.status,
redirected_url=str(response.url),
downloaded_files=downloaded_files,
)
await self.hooks['after_request'](result)
return result
except aiohttp.ServerTimeoutError as e:
await self.hooks['on_error'](e)
raise ConnectionTimeoutError(f"Request timed out: {str(e)}")
except aiohttp.ClientConnectorError as e:
await self.hooks['on_error'](e)
raise ConnectionError(f"Connection failed: {str(e)}")
except aiohttp.ClientError as e:
await self.hooks['on_error'](e)
raise HTTPCrawlerError(f"HTTP client error: {str(e)}")
except asyncio.exceptions.TimeoutError as e:
await self.hooks['on_error'](e)
raise ConnectionTimeoutError(f"Request timed out: {str(e)}")
except Exception as e:
await self.hooks['on_error'](e)
raise HTTPCrawlerError(f"HTTP request failed: {str(e)}")
async def crawl(
self,
url: str,
config: Optional[CrawlerRunConfig] = None,
**kwargsView on GitHub (pinned to 7e80152142)
Solutions
- Fix or verify the URL/host and check DNS (dig/nslookup) from the same environment.
- For local targets, confirm the dev server is up and the port matches.
- Configure proxy settings if the environment requires an egress proxy.
- Catch ConnectionError per URL during batch crawls and mark the URL dead rather than aborting the run.
Example fix
// before
results = [await crawler.arun(u) for u in urls] # one dead host kills the batch
// after
results = []
for u in urls:
try:
results.append(await crawler.arun(u))
except ConnectionError as e:
logger.warning(f"unreachable, skipping {u}: {e}") Defensive patterns
Strategy: try-catch
Validate before calling
import socket
from urllib.parse import urlparse
def host_resolves(url: str) -> bool:
host = urlparse(url).hostname
if not host:
return False
try:
socket.gethostbyname(host)
return True
except socket.gaierror:
return False Try / catch
try:
result = await crawler.arun(url)
except ConnectionError as e:
if "Connection failed" in str(e):
mark_unreachable(url) Prevention
- Verify dev servers are running before crawling localhost
- Check DNS/proxy egress in CI
- Filter dead domains from crawl lists early
When it happens
Trigger: Crawling a URL whose host does not resolve (typo, dead domain); target port not listening (dev server down); firewall/proxy blocking egress; TLS certificate rejected at handshake; IPv6-only host without IPv6 connectivity.
Common situations: Crawling localhost during local development when the dev server is not running; CI environments without network access or with DNS restrictions; expired domains in stale URL lists; corporate proxies requiring explicit configuration.
Related errors
- Unexpected status code for {url}
- Request timed out: {str(e)}
- HTTP client error: {str(e)}
- HTTP request failed: {str(e)}
- Unsupported export format: {format}
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/539c080c26970888.
Report an issue: GitHub.