ScreenshotNeo

BlogHow-to

PhantomJS Crashes with a Segmentation Fault While Taking Screenshots

A PhantomJS segmentation fault has no universal screenshot fix. Identify when it crashes, collect the right trace for your build, and decide whether to keep debugging or move to a maintained capture API.

By the ScreenshotNeo team4 October 20267 min read

A PhantomJS segmentation fault is a process crash, not a diagnosis, and the information in this title alone is not enough to identify its cause. There is no documented universal fix for screenshot-related segmentation faults. Start by recording the exact PhantomJS version and operating system, reducing the page and script to the smallest failing case, and collecting a crash trace that matches how PhantomJS was installed or built.

PhantomJS captures a page through its WebPage API: open the page, then call page.render. The documented output formats include PNG, JPEG, GIF, and PDF. A crash may happen during startup, page loading, or rendering, so first establish which step fails.

1. Record the environment and failure stage

Before changing libraries or reinstalling PhantomJS, write down the conditions that reproduce the fault. The project’s troubleshooting guide calls out version selection and multiple installations; its issue-reporting guide asks for version and operating-system details, reproducible steps, and a reduced test case.

  • Run phantomjs --version and save the exact output.
  • Record the operating system and release, CPU architecture, and how PhantomJS was installed or built.
  • Check which executable is being run with which phantomjs on Linux or macOS, or where phantomjs on Windows. If there are several installations, identify the one your script invokes.
  • Note whether the process crashes at startup, while opening the page, or specifically at page.render.
  • Record the input URL or local file, output format, viewport settings, and any delays or callbacks involved.
  • Compare whether a minimal page and a different output format also fail. Treat differences as evidence to narrow the reproduction, not as proof of a cause.

Historical reports describe different failures: a PDF-render report on Ubuntu with PhantomJS 1.9.7, and a minimal-code crash report with 2.1.1 on Ubuntu. They show that reports varied by version and circumstances; they do not establish that Ubuntu, PDF output, or one shared library is the general cause. See the PDF crash report and minimal-code report.

2. Reduce it to a runnable capture case

Use the basic documented sequence: create a WebPage, open a page, render it, and exit. Save this as capture.js:

var page = require('webpage').create();
var system = require('system');

var url = system.args[1];
var output = system.args[2] || 'shot.png';

if (!url) {
  console.log('Usage: phantomjs capture.js <url> [output.png]');
  phantom.exit(2);
}

page.viewportSize = { width: 1280, height: 800 };

page.open(url, function (status) {
  if (status !== 'success') {
    console.log('Page open failed: ' + status);
    phantom.exit(1);
    return;
  }

  var saved = page.render(output);
  console.log('Render returned: ' + saved + '; output: ' + output);
  phantom.exit(saved ? 0 : 1);
});

Run it with a page you control, then with the smallest input that still reproduces the fault:

phantomjs --version
phantomjs capture.js https://example.com shot.png

Replace https://example.com with the affected URL. If this minimal script succeeds but your application script crashes, add your original setup back a piece at a time: custom page settings, injected scripts, callbacks, and render options. If only a particular URL fails, preserve it or create a reduced local test page. A failure after opening but before output narrows the stage; it does not by itself reveal the underlying defect.

3. Collect a trace that matches your PhantomJS build

The official crash-reporting guide gives different procedures for official binaries and source builds. Do not mix their artifacts: it says crash dumps from official binaries are not useful for source builds.

Official binary

  1. Keep the crash dump produced by the failing run and identify the exact PhantomJS binary version.
  2. Obtain the symbol files that match that exact binary version.
  3. Use the project’s documented minidump_stackwalk procedure with the dump and matching symbols to produce a stack trace.
  4. If there is no stack output, follow the guide’s advice to remove error redirection and check permissions so the dump and trace can be written.

Symbols from a different build can make a trace misleading or unusable. Include the PhantomJS version and the symbol-file version with any report.

Build compiled from source

Build with debug symbols, run the reproducer under gdb, and request a backtrace after the crash:

gdb --args ./phantomjs capture.js https://example.com shot.png
(gdb) run
# After the process stops on the crash:
(gdb) bt

Save the complete backtrace and build details. The exact executable path and arguments may differ for your build. For this route, use the debugger trace rather than an official-binary crash dump.

4. Check environment branches only when the symptoms fit

Use the failure pattern to choose checks. These are documented troubleshooting possibilities, not established causes of this particular screenshot crash.

Observed pattern Useful check What it tells you
The version differs from what you expected, or behavior changes between shells or services Check the executable path and whether multiple PhantomJS installations exist. Confirms which binary the failing process actually launches.
HTTP pages work but HTTPS pages fail Check the SSL/TLS libraries available to that PhantomJS installation; the project guide identifies OpenSSL as a common library to inspect. Tests an HTTPS-specific environment branch. It does not explain crashes on HTTP pages.
The process is stopped or behaves differently under a locked-down Linux host Check whether SELinux policy is preventing PhantomJS from working, as described in the troubleshooting guide. Tests a host-policy possibility; do not assume SELinux is responsible without matching evidence.
The process starts, opens pages, and fails only on one render format or one page Compare a minimal page and another documented output format, holding other settings constant. Narrows the failing reproduction. A difference alone does not identify a root cause.

5. Report the crash so it can be reproduced

If you need to report the problem, include the information the project requests in its issue-reporting guide:

  • Exact PhantomJS version, operating system and version, architecture, and installation or build method.
  • Minimal command and script, along with the URL or local test input if shareable.
  • Steps to reproduce, the observed behavior, and the expected behavior.
  • Whether it fails at startup, page open, or rendering, and whether output format changes the result.
  • The matching minidump and symbol-based trace for an official binary, or the debug build’s gdb backtrace for a source build.
  • Relevant environment findings, such as duplicate installations or an HTTPS-only difference.

PhantomJS states that development is suspended until further notice. That affects expectations for ongoing compatibility and fixes; it does not tell you what caused an individual crash.

6. Choose whether to keep debugging or replace the capture path

Keep investigating when you need to preserve an existing PhantomJS workflow or when the reduced case and trace may identify a local environment issue. Consider moving capture to a maintained alternative when the old runtime is blocking a production process and you need a supported way to request screenshots. Save the reduced case and diagnostics either way; they document what failed and help you verify a replacement against the same page.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. A single GET request can return a PNG, JPEG, WebP, or PDF. This avoids managing a PhantomJS browser process for the capture request. Its capture flow accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before taking the shot; each of those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which page verdict and billing outcome applied. AI agents can use its MCP server tools take_screenshot, get_page_info, and capture_pdf.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

See the ScreenshotNeo API documentation for request options. The API also supports Python and Node.js clients:

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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', new Uint8Array(await res.arrayBuffer()));

ScreenshotNeo offers 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.

Performance, reliability, and cost considerations

  • Debugging cost: Reduce the case before repeatedly rerunning a complex job. A small reproducible input makes it easier to compare startup, page-open, and render behavior and to collect a useful trace.
  • Reliability: A successful run on one machine does not prove the crash is fixed in every environment. Record the version, operating system, and build method alongside the reproduction and repeat it in the environment where the failure matters.
  • Maintenance: PhantomJS development is suspended, so weigh the effort of maintaining an old runtime against moving the screenshot step to another capture path.
  • ScreenshotNeo cost: The free plan includes 1,000 shots per month without a card. Paid tiers are Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free. Every feature is included on every plan. Only clean shots are billed, and cache hits are free.

FAQ

Does a segmentation fault mean the screenshot itself is corrupt?

No conclusion about the output follows from the signal alone. The process may crash before, during, or after rendering; identify the failing stage and inspect the resulting artifacts and trace.

Will changing from PNG to PDF fix the crash?

There is no universal format workaround established by the available reports. Comparing formats can narrow a reduced reproduction, but a format-specific result does not establish its root cause.

Can a crash report guarantee a PhantomJS fix?

No. The project says development is suspended and notes its limited volunteer maintenance capacity. A detailed report improves reproducibility, but does not guarantee a fix.