Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Target closed is a symptom, not a diagnosis. First identify which Puppeteer operation failed; then determine whether your code closed the page while asynchronous work was still running, or whether Chromium or the target crashed. Await page work before cleanup, and use Lambda logs plus the exact deployed versions and launch configuration to investigate crashes. Increasing memory or changing browser flags is not a universal fix.

What “Target closed” means—and what it does not tell you

Puppeteer communicates with Chromium through browser targets and the Chrome DevTools Protocol. A “Target closed” error means the target Puppeteer was trying to use is no longer available. The message alone does not establish why it became unavailable: your code may have closed it, Chromium may have exited, or a target may have crashed.

The failing method is an important clue. Protocol error (Runtime.callFunctionOn): Target closed can occur when asynchronous work continues after the page or browser closes. AWS documents this lifecycle case in its CloudWatch Synthetics troubleshooting guidance. A different sequence—where puppeteer.launch() succeeds but browser.newPage() fails with Target.createTarget: Target closed—may point toward a target or browser-process problem instead. The wording is a starting point for diagnosis, not proof of a single root cause.

Start with the failing operation

Before changing dependencies or Lambda settings, preserve the complete error and stack trace. Record which step was running when it failed:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • puppeteer.launch(): investigate browser startup and the deployed executable, runtime, architecture, and launch configuration.
  • browser.newPage(): check whether launch actually completed, and look for a process exit, disconnect, or target crash between launch and page creation.
  • Navigation, page.evaluate(), screenshot, or PDF generation: check whether the page or browser was closed while that operation—or other work it started—was still pending.
  • Cleanup: check whether an earlier operation failed or is still running when your code calls page.close() or browser.close().

Keep the exact method and error string in your notes. Two failures that both contain “Target closed” may need different fixes.

Fix lifecycle races before changing Chromium

For the asynchronous-work variant, ensure that every operation using the page or browser is awaited before cleanup. A common cause is a close call in a finally block, handler return, timeout, or concurrent task that runs while navigation, evaluation, screenshot, or PDF work is still in progress. Also check whether a promise was started without being awaited or whether independent tasks can close the same page.

The following example shows the cleanup order for a request handler. It assumes your Lambda deployment already has a compatible Puppeteer/Chromium setup that makes puppeteer.launch() work. It illustrates promise sequencing; it does not supply a Lambda-specific Chromium binary or launch flags.

const puppeteer = require('puppeteer');

exports.handler = async () => {
  let browser;
  let page;

  try {
    browser = await puppeteer.launch();
    page = await browser.newPage();

    await page.goto('https://example.com', {
      waitUntil: 'networkidle0',
    });

    const title = await page.title();
    const screenshot = await page.screenshot({ type: 'png' });

    return {
      statusCode: 200,
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ title, screenshotBytes: screenshot.length }),
    };
  } finally {
    if (page) {
      await page.close();
    }
    if (browser) {
      await browser.close();
    }
  }
};

The key property is that the handler awaits navigation and all page operations before its finally block closes anything. In a real function, return the actual result your caller needs; do not leave screenshot, evaluation, or other page work running in the background after the handler is ready to finish. If you have multiple concurrent operations, wait for all of the ones that use the page before closing it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find out whether Chromium or the target crashed

If the error occurs during page creation or a page operation despite orderly cleanup, investigate the browser process rather than assuming a lifecycle race. Review the Lambda logs around the failure for Chromium stderr, an exit or disconnect, target-crash messages, and browser setup errors. A launch promise resolving does not, by itself, prove that Chromium remains healthy for the next operation.

For example, the historical Puppeteer issue #6776 reports that launch succeeded before a target crash and Target.createTarget: Target closed. The reporter described Puppeteer 5.5.0, Amazon Linux 2, Node.js 12.19, and 1 GB of Lambda memory. Those details describe that 2021 report; they are not a current compatibility recipe, a memory recommendation, or proof of what caused the failure.

Record the deployed browser environment

Capture the exact deployed configuration before upgrading, downgrading, or swapping browser packages. Local success is useful evidence, but it does not establish that the Lambda artifact has the same browser setup.

  • Lambda Node.js runtime and architecture.
  • Puppeteer or Puppeteer Core version.
  • Chromium package, binary, or Lambda layer and its version.
  • The executable path Puppeteer actually uses.
  • Headless mode and launch arguments.
  • The failing operation and the relevant log output, including browser stderr if available.
  • Whether the same deployment artifact behaves differently in local or Lambda-like execution.

Compare these details as a set. A version number on its own is not enough to establish that the browser binary, runtime, and launch setup are compatible. Puppeteer maintains a troubleshooting guide for browser setup issues; use it to investigate the configuration you have rather than copying flags from an unrelated Lambda report.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A newer case report illustrates why restraint matters: Sparticuz Chromium issue #438, opened in September 2025, describes a Lambda PDF-generation failure involving Chromium 137–138, Puppeteer or Puppeteer Core 24.10.2–24.19.0, Node.js 22.15.1, and x86_64. The report does not establish a single cause or a generally supported version combination. Treat it as a case to compare against your own environment, not a compatibility guarantee.

Check Lambda resources using evidence

Review CloudWatch logs, execution duration, timeout behavior, and the function’s configured memory. AWS explains how to configure Lambda memory, but the setting’s availability does not show that memory caused a particular target-close error. The 1 GB setting in issue #6776 is the reporter’s configuration, not a minimum or recommended amount.

Change memory as a controlled diagnostic only when logs or runtime behavior give you a reason to suspect resource pressure. Record the original setting and the exact failing operation, change one relevant variable, then run the same deployed artifact and compare the result. If the evidence points instead to a page closing too early or a browser setup problem, changing memory alone does not address that diagnosis.

Troubleshoot by symptom

Observed symptom What to check Next step
Runtime.callFunctionOn: Target closed after cleanup begins Unawaited page work, a close in a finally block, handler return, timeout, or competing task. Await all work using the page or browser before closing it; rerun the same operation.
launch() appears to succeed, then Target.createTarget: Target closed Browser stderr, process exit or disconnect, and target-crash evidence between launch and newPage(). Compare runtime, architecture, package and binary versions, executable path, and launch options; investigate the observed browser setup failure.
Failure occurs during PDF generation Whether the page is still open and the PDF promise is awaited; also inspect browser logs and the deployed environment. Separate lifecycle checks from environment checks. A PDF-related case report is not, by itself, proof of a universal Chromium defect.
Only the Lambda deployment fails Differences between the deployed artifact and local setup, including runtime, architecture, layer or binary, executable path, and launch arguments. Compare the recorded configurations and reproduce with the deployed artifact where possible before changing one variable.
Error persists after a memory change Whether resource pressure was actually visible in logs or runtime behavior, and whether the original lifecycle or browser evidence was addressed. Do not keep increasing memory as a substitute for identifying the failing stage and process state.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make one change, then verify in Lambda

  1. Save the complete stack trace and identify the failing operation.
  2. Check promise sequencing and cleanup order. Correct a lifecycle race if one is present.
  3. If the browser may have exited or crashed, inspect logs and record the complete deployed environment.
  4. Use the Puppeteer troubleshooting guide to investigate setup issues that match the evidence. Avoid applying flags or package changes just because they appear in another case report.
  5. Change one relevant variable at a time and deploy the same artifact to the target Lambda runtime.
  6. Repeat the same operation and compare its logs and outcome. Treat a fix as verified only after that deployed test succeeds.

This approach distinguishes a confirmed lifecycle correction from a guess about versions or resources. The cited issue reports are examples from particular environments, not tests of your function.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your task is simply to capture a webpage as an image or PDF, you can use ScreenshotNeo instead of maintaining a Puppeteer/Chromium browser setup for that capture. It is a screenshot API and MCP server, not a repair for arbitrary Puppeteer automation: use Puppeteer when you need custom browser behavior the API does not provide.

One GET request returns a screenshot or PDF. See the ScreenshotNeo API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
  • Cookie/consent banners are accepted and removed, and known newsletter popups and chat widgets are removed before capture; each of those steps can be turned off.
  • Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; the response identifies the page verdict and billing status in headers.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The Free plan includes 1,000 screenshots per month with no card required; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.

Frequently Asked Questions

Does “Target closed” mean the website closed the connection?

Not necessarily. It says Puppeteer could no longer use the target; the message alone does not identify whether your code closed it or the browser or target failed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.