How to Abort HTTP Requests in Puppeteer
Use Puppeteer request interception to abort selected HTTP requests while letting the rest continue. Includes safe handler patterns, filtering examples, troubleshooting, and a no-browser-setup option.
Direct answer: Enable request interception with page.setRequestInterception(true) before navigation, then handle every intercepted request. Call request.abort() for requests that match your blocking rule and request.continue() for everything else. An unresolved intercepted request can stall page loading.
Minimal runnable example
Install Puppeteer, save this as abort-requests.mjs, and run it with Node.js. The example blocks requests whose URLs end in .png or .jpg, following Puppeteer’s documented pattern. Adjust the rule for your goal and target site.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
const url = request.url();
if (url.endsWith('.png') || url.endsWith('.jpg')) {
void request.abort();
} else {
void request.continue();
}
});
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
} finally {
await browser.close();
}
The handled-state guard matters when dependencies or other listeners may also resolve requests. The event callback does not need to be asynchronous in this example because its rule uses only the request URL.
How interception works
page.setRequestInterception(true) activates the request-resolution methods abort(), continue(), and respond(). After interception is enabled, each request waits until it is resolved, answered, aborted, or completed from the browser cache. Register your handler before navigation if you need to affect navigation requests.
- Create a page.
- Enable interception.
- Register a request listener that resolves every request path.
- Navigate or perform the action that triggers the requests.
- Close the browser when the work is complete.
Puppeteer’s [Page.setRequestInterception() API] documents the prerequisite and the stall behavior. Its [network interception guide] explains handler coordination.
Choose a blocking rule
Requests expose properties such as url() and resourceType(). Use the narrowest rule that fits the task. Blocking a resource can alter page behavior or appearance, so inspect the result on the pages you automate.
Block by URL suffix
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
const url = request.url().toLowerCase();
const shouldBlock = url.endsWith('.png') || url.endsWith('.jpg');
void (shouldBlock ? request.abort() : request.continue());
});
A suffix rule is simple, but it may miss query-string URLs such as image.jpg?size=large. Parse the URL or use a resource-type rule if the site’s URL patterns vary.
Block by resource type
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
const shouldBlock = request.resourceType() === 'image';
void (shouldBlock ? request.abort() : request.continue());
});
This applies to requests Puppeteer identifies as images, regardless of their filename. Whether this is appropriate depends on the task: images may be needed for visual checks, and page scripts or styles may depend on other resources.
Block a specific host or path
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
let shouldBlock = false;
try {
const url = new URL(request.url());
shouldBlock = url.hostname === 'ads.example' || url.pathname.startsWith('/tracking/');
} catch {
// If the URL cannot be parsed, let it pass through.
}
void (shouldBlock ? request.abort() : request.continue());
});
Choose explicitly how malformed or unexpected URLs should be treated. This sample passes them through.
Handle multiple listeners and asynchronous rules
Another listener may already have resolved a request. Check request.isInterceptResolutionHandled() immediately before resolving it. If your handler awaits work, check again after the await; the state can change while the handler is suspended.
page.on('request', async request => {
if (request.isInterceptResolutionHandled()) return;
const shouldBlock = await shouldBlockUrl(request.url());
// Another handler may have resolved it during the await.
if (request.isInterceptResolutionHandled()) return;
await (shouldBlock ? request.abort() : request.continue());
});
For handlers that need to cooperate, Puppeteer also documents Cooperative Intercept Mode. Every participating resolver must provide a numeric priority for cooperative resolution; if a handler resolves without one, legacy behavior can resolve immediately. In cooperative mode, asynchronous handlers are awaited, the highest priority wins, and ties resolve in this order: abort, respond, continue. See the [official guide] for the current details.
Abort, continue, or respond
| Method | Effect | Use when |
|---|---|---|
request.abort() |
Fails the request. | A matching request should not be sent or completed. |
request.continue() |
Lets the request proceed. | The request does not match your blocking rule. |
request.respond() |
Supplies a response from your code. | You need to fulfill the request locally rather than fetch it. |
abort(errorCode?, priority?) accepts optional arguments. The appropriate error code depends on the installed Puppeteer version and the application’s needs; check the versioned API documentation if you pass one. Calling abort() with no arguments is sufficient for ordinary filtering. See the [abort() API] and [HTTPRequest API].
Know how aborted requests appear
An aborted request is a failed request: Puppeteer reports it through the request failure lifecycle rather than as a finished request. An HTTP response with status 404 or 503 is different: it is still a completed request from the request-event perspective. Use response status checks for HTTP errors and request failure events for transport or abort outcomes.
page.on('requestfailed', request => {
console.log('Request failed:', request.url(), request.failure()?.errorText);
});
page.on('response', response => {
if (response.status() >= 400) {
console.log('HTTP error response:', response.status(), response.url());
}
});
Alternative: connection-level URL blocklist
Puppeteer’s ConnectOptions reference describes an experimental URL-pattern blocklist for Chrome when Puppeteer is attached to CDP targets. It can provide a broad URL restriction at connection setup, while page interception lets code inspect individual requests and choose an action. The blocklist is Chrome-only and is not a complete network sandbox. Check the [ConnectOptions reference] for the version you use.
Performance, reliability, and cost
- Performance: Interception adds a decision point to requests and they wait for resolution. Keep synchronous rules quick; avoid unnecessary asynchronous lookups in the handler.
- Reliability: Always provide a pass-through path, and guard against other handlers resolving first. Install interception before the requests you intend to filter.
- Page behavior: Blocking scripts, styles, or images may change rendering or break page behavior. Validate the resulting page against the purpose of the automation.
- Cost: Puppeteer itself does not define a per-request interception charge in these APIs. Compute and infrastructure costs depend on where and how you run the browser.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Navigation hangs or takes much longer | An intercepted request was left unresolved, or the navigation waits for resources that were blocked. | Ensure every path calls abort, continue, or respond. Review the chosen waitUntil condition. |
Request is already handled or resolution errors |
Another listener or dependency resolved the request. | Check isInterceptResolutionHandled() immediately before resolving; check again after each await. |
| Requests are not being blocked | Interception was enabled too late, or the matching rule does not match actual URLs. | Enable and register before navigation. Log request.url() and inspect query strings, casing, redirects, and resource types. |
| Page looks broken after filtering | A blocked resource was required for layout or functionality. | Narrow the rule and compare the page with and without the block. |
A 404 does not appear as requestfailed |
HTTP error status is a completed response, not an aborted request. | Listen for response and inspect response.status(). |
| A blocklist option has no effect | The documented option is experimental and limited to Chrome/CDP attachment. | Check the installed Puppeteer version and use page interception for per-request filtering. |
Or skip the browser setup
If your goal is a screenshot rather than custom browser request handling, ScreenshotNeo returns a screenshot or PDF from one API request. See the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners are accepted and removed before capture; known consent platforms, newsletter popups, and chat widgets can be removed, and each step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers report the page verdict and billing status.
- An MCP server gives AI agents tools for screenshots, page information, and PDF capture.
- The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.
Create a free ScreenshotNeo account and start with 1,000 screenshots a month at no charge.
FAQ
Can I abort a request after it has started?
Request interception resolves a request as it is intercepted. Enable it before the request is made if you want to decide whether that request proceeds.
Does aborting a request cancel the whole page?
No. It fails that request. The effect on the page depends on what the site needed the resource for and on the navigation or wait condition used by your script.
Can I block requests without inspecting them in a page listener?
The documented connection-level URL blocklist is an experimental Chrome-only option with limitations. For application-specific per-request decisions, use page interception.


