How to Get the Remote Address of a Puppeteer Response
Call `response.remoteAddress()` to read the IP address and port Puppeteer used to connect to the remote server. Here’s a runnable example and what to expect when either value is unavailable.
Call response.remoteAddress() on a Puppeteer HTTPResponse. It returns an object with optional ip and port properties: the address and port used to connect to the remote server. Both values may be absent, so handle them as optional. See the Puppeteer API reference and the RemoteAddress type.
Get the address from a response event
The response event supplies an HTTPResponse. Call its synchronous remoteAddress() method inside the handler:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
page.on('response', response => {
const { ip, port } = response.remoteAddress();
console.log({
url: response.url(),
ip: ip ?? null,
port: port ?? null,
});
});
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
} finally {
await browser.close();
}
})();
Install Puppeteer in the project before running the example (for example, npm install puppeteer). The example logs an address for every response, including subresources; filter by URL or resource type if you only want a particular response.
Capture the main document response
If you need the navigation’s main document response rather than every response event, use the value returned by page.goto():
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
const response = await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
});
if (!response) {
console.log('Navigation did not provide an HTTP response.');
return;
}
const { ip, port } = response.remoteAddress();
console.log({
url: response.url(),
ip: ip ?? null,
port: port ?? null,
});
} finally {
await browser.close();
}
})();
The navigation response can be null, so check it before calling a method. The optional chaining fallback in the output keeps missing address fields explicit as null instead of logging undefined.
What the returned address represents
Puppeteer documents the result as the IP address and port used to connect to the remote server. The object’s ip field is an optional string and port an optional number.
This is not the response URL, a hostname, or a separate DNS lookup. Don’t assume that an address will always be populated in every network or response scenario; the API documentation does not promise availability for each case.
Filter and record useful responses
A page can receive many responses. Filter before logging when you only care about the main document, a specific host, or a particular resource type:
page.on('response', response => {
const url = new URL(response.url());
if (url.hostname !== 'example.com') return;
const { ip, port } = response.remoteAddress();
console.log({
url: response.url(),
status: response.status(),
ip: ip ?? null,
port: port ?? null,
});
});
For the top-level navigation alone, the page.goto() example is simpler. For diagnostic logs, include the response URL and status alongside the optional address so you can tell which response the values belong to. Avoid treating the IP as a stable identity for a hostname: this method reports connection information for a response, not a canonical DNS record.
Options and edge cases
- Method is synchronous: call
remoteAddress()directly; there is no promise to await. - Optional fields: check
ipandportindependently. Do not infer one from the other. - No navigation response:
page.goto()may returnnull; guard it before access. - Multiple responses: the page response event includes document and subresource responses. Filter if you need a narrower set.
- Scope of the value: it is the connected remote server address and port, not a hostname or URL.
- Unspecified cases: the API reference does not document a complete behavior matrix for cache, service-worker, proxy, or other transport cases. Check whether fields are present rather than relying on assumptions about those scenarios.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
response.remoteAddress is not a function |
The value is not a Puppeteer HTTPResponse, or a different object was passed to the handler. |
Use the response argument from Puppeteer’s page response event or the response returned by page.goto(). Confirm the installed Puppeteer API version. |
response is null |
The navigation did not provide an HTTP response. | Guard the result of page.goto() before calling remoteAddress(). |
ip or port logs as missing |
The return type marks each property optional; the API does not guarantee both values in every case. | Handle missing values explicitly, such as with ?? null. Don’t replace them with a DNS lookup and claim it is the same connection value. |
| Many address lines appear | The response event fires for multiple page responses, including subresources. | Filter on response.url(), or read the main navigation response from page.goto(). |
| Browser launch or navigation fails | This is separate from remoteAddress(); the browser may not start or the page may not load. |
Resolve the launch/network error first. Only call the method after obtaining a Puppeteer response. |
Performance, reliability, and cost
remoteAddress() is a synchronous accessor on an existing response object. The examples add no extra request or DNS lookup to obtain the reported value. For high-volume pages, keep response handlers focused and avoid excessive logging, which can create more overhead than reading the fields.
The method reports connection details for the response; it does not make the navigation more reliable or establish that the same address will be used on another request. Puppeteer itself runs in your environment, so browser runtime and hosting costs depend on that environment.
Or skip the browser setup
If you need a rendered screenshot instead of connection diagnostics, ScreenshotNeo returns an image or PDF from one GET request. It does not expose Puppeteer’s remote address; use Puppeteer’s method above when that connection value is what you need. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
See the ScreenshotNeo API documentation. For example, this cURL request saves a WebP screenshot:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Is remoteAddress() asynchronous?
No. It returns the address object synchronously.
Does it return a hostname?
No. It returns optional IP and port fields.
Can I use it for every response from a page?
You can call it on Puppeteer response objects, but handle optional fields and filter events according to which responses you need.
Does the address identify the origin permanently?
No. It describes the address and port used for that connection; it is not a guarantee about future connections or a hostname lookup.


