Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
When a PhantomJS page appears without its JavaScript, first determine which layer failed: the script never ran, its URL was never requested, the request failed or timed out, an exception stopped execution, or a different PhantomJS binary is being used. Log the navigation status, every relevant resource error, and page-side stack trace before changing timeout values. The steps below use PhantomJS’s documented WebPage API and are intended for maintaining legacy scripts, not for new browser automation.
Start by proving which failure you have
“JavaScript did not load” describes several different problems. A reliable diagnosis separates them using observable evidence:
- Navigation failure:
page.openfinishes withfail. - No script request: the page loads, but the expected script URL never appears in request logs. The markup may not include it, conditional code may skip it, or an earlier exception may prevent the request.
- Resource failure: the script URL is requested and then reports an error or timeout. This points to URL reachability, TLS, proxy, or server problems.
- Execution failure: the resource arrives, but page state is wrong or a JavaScript exception is thrown.
- Environment mismatch: the same code behaves differently because another PhantomJS version or build is being invoked.
Do not treat a successful main-page load as proof that an application has finished rendering. onLoadFinished reports navigation completion; single-page applications can continue making requests and running asynchronous code afterward.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
PhantomJS itself is legacy software: its repository is archived (the archive notice is dated May 30, 2023). The official behavior described here remains useful for existing deployments, but compatibility work should be weighed against that maintenance status.
#1 Best Overall
1. Verify the executable and version
Run the version command in the exact shell, container, service account, or CI image that launches the failing script:
phantomjs --version
Record the printed version, the binary path, and whether it came from an operating-system package or a downloaded build. Multiple installations can make a command resolve to a different executable than the one you tested. Compare PATH, the absolute executable path, and library files between a working and failing machine. The official troubleshooting guide recommends this check before deeper page debugging: PhantomJS Troubleshooting.
2. Enable JavaScript before the first navigation
PhantomJS documents javascriptEnabled as enabled by default, but set it explicitly so the runtime configuration is visible. Settings must be assigned before the first page.open; the settings documentation states that they apply only during that initial call (WebPage settings).
Recommended Free Tools
var page = require('webpage').create();
page.settings.javascriptEnabled = true;
page.settings.resourceTimeout = 10000;
page.open('https://example.com/', function (status) {
console.log('Page load status: ' + status);
phantom.exit();
});
Changing page.settings after page.open cannot retroactively enable scripts for that navigation. Create a new page and configure it before opening if you need to retry.
Rank #2
3. Add complete navigation, resource, and exception logging
Use all of the relevant callbacks while investigating. This diagnostic script records the URL, status, timeout metadata, resource errors, console messages, and page-side stack frames:
var page = require('webpage').create();
page.settings.javascriptEnabled = true;
page.settings.resourceTimeout = 10000;
page.onResourceRequested = function (request) {
console.log('Request: ' + request.url);
};
page.onResourceTimeout = function (request) {
console.log('Timeout: ' + request.url +
' code=' + request.errorCode +
' message=' + request.errorString);
};
page.onResourceError = function (error) {
console.log('Resource error: ' + error.url +
' code=' + error.errorCode +
' message=' + error.errorString);
};
page.onConsoleMessage = function (message, lineNum, sourceId) {
console.log('Console: ' + message +
' (' + sourceId + ':' + lineNum + ')');
};
page.onError = function (message, trace) {
console.log('Page error: ' + message);
trace.forEach(function (frame) {
console.log(' ' + frame.file + ':' + frame.line);
});
};
page.open('https://example.com/', function (status) {
console.log('Page load status: ' + status);
// Test an application-specific ready condition here.
phantom.exit();
});
The open callback supplies success or fail (open). The timeout callback includes the requested URL, error code, and error string (onResourceTimeout). Keep those values in logs; a generic “JavaScript failed” message is not enough to identify the layer.
Why is PhantomJS not loading JavaScript?
The script tag or conditional loader never created a request
If the expected URL is absent from onResourceRequested output, inspect the delivered HTML and its script tags. A feature flag, dynamically constructed URL, content-security decision, or earlier exception can prevent the request from being created. Use onError and console logging first. Remote debugging can help inspect the page when static logs do not explain the branch.
The request was issued but failed
Match the exact script URL in onResourceError or onResourceTimeout. Check DNS, redirects, proxy configuration, authentication, and whether the URL is reachable from the PhantomJS host. A timeout only proves that the configured deadline elapsed; increasing it cannot repair an invalid URL, blocked request, or unsupported protocol feature.
The script arrived but execution stopped
Read the message and every stack frame from page.onError. Syntax errors, missing APIs, and application exceptions can leave the DOM looking as if JavaScript never loaded. PhantomJS’s troubleshooting documentation notes that page exceptions can be printed with detailed stack information (official troubleshooting guide).
How do I see JavaScript errors in PhantomJS?
Attach both page.onError and page.onConsoleMessage. They answer different questions: onError captures thrown page exceptions and stack frames, while the console handler captures messages explicitly written by page code. Do not infer that a missing onError event means the page is error-free. A report about PhantomJS 2.1.1 builds found that console.error could be routed differently between builds (Issue #15166), so retain both streams and compare behavior on the actual binary you run.
Why does PhantomJS work over HTTP but fail over HTTPS?
When HTTP succeeds and HTTPS does not, treat TLS as a primary suspect rather than assuming the JavaScript source changed. Inspect the SSL/TLS libraries available to the PhantomJS executable and collect resource callback output. Look for the HTTPS script URL, its redirect chain, and the precise error code or timeout message. Compare the binary and shared libraries on working and failing machines. The official troubleshooting page discusses SSL/TLS investigation and network monitoring (PhantomJS Troubleshooting).
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →If the HTTPS resource never appears in request logs, investigate page logic or an earlier exception. If it appears and then errors, the failure is at the network or TLS layer. PhantomJS’s age means modern certificate chains, protocol versions, or ciphers may not be supported by a particular build; verify the evidence in your environment before attempting workarounds.
Rank #4
Wait for application readiness, not an arbitrary sleep
After page.open reports success, poll an observable condition that means your application is ready: a known element, a non-empty text node, or a global state flag. Use a finite deadline and log the condition when it expires. The official API documents load and resource callbacks but does not prescribe a universal delay, so a large fixed sleep is not a dependable fix.
function waitForReady(test, deadline, done) {
if (test()) { done(true); return; }
if (Date.now() >= deadline) { done(false); return; }
setTimeout(function () {
waitForReady(test, deadline, done);
}, 100);
}
page.open('https://example.com/', function (status) {
if (status !== 'success') {
console.log('Navigation failed: ' + status);
phantom.exit();
return;
}
var deadline = Date.now() + 10000;
waitForReady(function () {
return page.evaluate(function () {
return !!document.querySelector('#app-ready');
});
}, deadline, function (ready) {
console.log('Ready condition: ' + ready);
phantom.exit();
});
});
Use the evidence to choose the next check
| Observed evidence | Likely layer | Next check |
|---|---|---|
page.open reports fail |
Main navigation or environment | Review URL, resource events, TLS, proxy settings, and the executable. |
| Main page succeeds; script URL is absent | Markup, conditional loading, or earlier execution error | Inspect script tags and onError/onConsoleMessage output. |
| Script URL is requested, then times out or errors | Network or resource loading | Check reachability, redirects, TLS, proxy, and callback metadata. |
| Resource loads but page state is wrong | Execution, unsupported browser behavior, or async readiness | Read stack traces, console output, and the application-ready condition. |
| Results differ across machines | Binary, build, or library mismatch | Compare phantomjs --version, binary origin, paths, and TLS libraries. |
Or skip the browser setup
If your goal is a clean image or PDF rather than maintaining a PhantomJS runtime, ScreenshotNeo provides a website screenshot API and MCP server. A single request can capture a URL without installing PhantomJS:
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 documentation for request options and response details. Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.
Sign up free for ScreenshotNeo and use the one-call approach when legacy browser debugging is not the work you need.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common errors and recovery steps
“Page load status: fail”
Keep the exact URL and all resource callbacks. Test DNS and connectivity from the PhantomJS host, then inspect TLS and proxy settings. Confirm that the intended executable is running.
Best Value
Only one third-party script times out
Use the timeout URL, error code, and error string to identify that dependency. Check whether the host blocks the PhantomJS user agent, requires authentication, or is unreachable from the runtime. Raise resourceTimeout only after measuring that the request is valid but slower than the current deadline.
No exception appears, but the DOM is empty
Enable console and error handlers, verify that the script request occurred, and wait on a page-specific readiness condition. Build-dependent console routing means one callback alone is insufficient.
It works locally but not in CI
Print the version and absolute binary path in both environments. Compare packaged versus downloaded builds, environment variables, proxy configuration, and SSL/TLS libraries. Reproduce with the same URL and retain callback logs.
Maintenance and cost decisions
Do not spend unlimited time forcing an archived engine to execute modern application code. If logs show unsupported browser APIs or TLS behavior and you control the site, a maintained browser automation stack may be the longer-term engineering path; this evidence set does not establish one specific replacement. If you only need screenshots or PDFs, an API can remove the browser-installation and page-cleanup work, while PhantomJS remains appropriate for a script you must preserve and understand.
FAQ
Does PhantomJS have JavaScript disabled by default?
No. The documented default for javascriptEnabled is true; set it explicitly before navigation so the runtime state is unambiguous.
Can I fix every failure by increasing the timeout?
No. A timeout value cannot correct a bad URL, blocked request, TLS incompatibility, or a script exception. Use the URL, error code, and error string to identify the cause first.
What should I log for a reproducible bug report?
Record the PhantomJS version and binary origin, target URL, page.open status, requested resource URLs, timeout and error metadata, console messages, page-error stack frames, and whether HTTP and HTTPS differ.
Quick Recap
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.

