apify/crawlee · warning · SessionError
<dynamic: message extracted from proxied error via getMessag
Error message
<dynamic: message extracted from proxied error via getMessageFromError>
What it means
Inside the crawler's requestFunction, errors are inspected after the request fails; if `isProxyError()` classifies the thrown error as a proxy-level failure (e.g. proxy connection refused, 407, tunnel errors), it is re-thrown as a SessionError carrying the original message extracted via getMessageFromError. This marks the session as bad so the request is retried through a different proxy instead of failing the whole request.
Source
Thrown at packages/http-crawler/src/internals/http-crawler.ts:708
/**
* Function to make the HTTP request. It performs optimizations
* on the request such as only downloading the request body if the
* received content type matches text/html, application/xml, application/xhtml+xml.
*/
private async requestFunction({ request, session, proxyUrl }: RequestFunctionOptions): Promise<Response> {
const opts = this.getRequestOptions(request, session, proxyUrl);
try {
return await this.requestAsBrowser(opts, session);
} catch (e) {
if (e instanceof Error && e.constructor.name === 'TimeoutError') {
this.handleRequestTimeout(session);
return new Response(); // this will never happen, as handleRequestTimeout always throws
}
if (this.isProxyError(e as Error)) {
throw new SessionError(this.getMessageFromError(e as Error) as string);
} else {
throw e;
}
}
}
/**
* Encodes and parses response according to the provided content type
*/
private async parseResponse(request: CrawleeRequest, response: Response) {
const { status } = response;
const { type, charset } = parseContentTypeFromResponse(response);
const { response: reencodedResponse, encoding } = this.encodeResponse(request, response, charset);
const contentType = { type, encoding };
if (status >= 400 && status <= 599) {
this.statistics.registerStatusCode(status);
}View on GitHub (pinned to dbe57fb09c)
Solutions
- Verify proxy credentials (username/password) and proxy URL in your ProxyConfiguration are current.
- Test the proxy directly (curl -x proxy_url target_url) to confirm it works outside crawlee.
- Ensure session pool is enabled so bad sessions are retired and the request retries on a healthy proxy.
- Check your proxy provider's dashboard for quota exhaustion or IP pool health; switch pools if needed.
Example fix
// before
proxyConfiguration: await Actor.createProxyConfiguration({ groups: ['RESIDENTIAL'] }),
// after: validate proxy before crawling
const proxyConfiguration = await Actor.createProxyConfiguration({ groups: ['RESIDENTIAL'] });
const proxyUrl = await proxyConfiguration.newUrl();
const res = await got('https://api.apify.com/v2/public-proxy-ip', { proxyUrl, throwHttpErrors: false });
if (res.statusCode >= 400) throw new Error(`Proxy unhealthy: ${proxyUrl}`); Defensive patterns
Strategy: try-catch
Validate before calling
const proxyUrl = await proxyConfiguration.newUrl();
const probe = await got('https://httpbin.org/ip', { proxyUrl, throwHttpErrors: false, timeout: 10000 });
if (probe.statusCode !== 200) throw new Error(`Proxy probe failed: ${probe.statusCode}`); Type guard
function isProxySessionError(err: unknown): err is SessionError {
return err instanceof SessionError && /proxy/i.test(err.message);
} Try / catch
try {
await crawler.run(requests);
} catch (err) {
if (err instanceof SessionError && /proxy|tunnel|407/i.test(err.message)) {
log.error(`Proxy infrastructure problem, aborting: ${err.message}`);
return;
}
throw err;
} Prevention
- Validate proxy credentials and quota before starting large crawls.
- Smoke-test one request through the proxy pipeline before full runs.
- Prefer provider proxy groups with health monitoring; rotate groups on repeated proxy errors.
- Log proxy session IDs on failure to correlate with provider logs.
When it happens
Trigger: The underlying HTTP request (got) rejects with a proxy-related error while a proxyConfiguration is in use — e.g. proxy authentication failed, proxy unreachable, or the proxy returned an error response.
Common situations: Expired or wrong proxy credentials; datacenter IPs blocked by the target; proxy provider outage; residential proxy session exhausted; running locally without the proxy reachable from the network.
Related errors
- ${this.getMessageFromError(error)}
- Request blocked - received ${statusCode} status code.
- <dynamic: blocked-request message returned by isRequestBlock
- ${colors.yellow(`[${label}]`)}: Attempt ${attempt + 1} of ${
- The current SessionPool instance couldn't find a valid sessi
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/3719bca36b0bcde5.
Report an issue: GitHub.