Errors & limits
Errors are JSON: {"error": "…"}, sometimes with extra fields. On the free Community plan, errors caused by its limits (community_capacity_full, daily_quota_exhausted, hourly_quota_exhausted, threads_exceeded, profiles_disabled, keep_alive_requires_dedicated) also carry "upgrade": {"message": "…", "url": "https://cdpfleet.com/upgrade"} — what a paid plan changes, linking to the Community vs paid page; the error code and HTTP status stay the same. Launch responses:
| Status | error | Meaning | What to do |
|---|---|---|---|
400 | invalid_json | The body isn't a JSON object. | Fix the request. |
400 | invalid_memory | memory isn't one of the JSON numbers 1, 2, 3 or 4 (it's a multiplier, not megabytes). | Send "memory": 2 (or 3, 4), or leave it out. |
400 | invalid_channel / invalid_version | No server in the fleet has that channel or version (pin). The message lists the channels or majors this browser has. | Pick one from the message; don't retry as is. |
400 | invalid_downloads | downloads isn't true or false. | Send a JSON boolean. |
403 | downloads_not_available | "downloads": true on a plan that doesn't keep downloads (Community). | Use a paid plan (Community vs paid), or catch the download in code with Playwright's download.saveAs(). |
400 | proxy_required | The launch has no proxy and no Community proxy is available for your plan right now (rare). | Add your proxy (formats), or your own VPN on a dedicated plan. |
400 | invalid_proxy | A cdpfleet-resi token that doesn't match the grammar, or one used inside a list of proxies. The message names the wrong part. | Fix the token (residential proxy). |
400 | tunnel_not_available | vpn_tunnel with a default proxy that isn't a cdpfleet-resi Tier 1/2 token — or your own proxy, on dedicated plans (or a live swap away from one). reason says why. | Use a Tier 1/2 cdpfleet-resi token, or launch without vpn_tunnel (VPN Tunnel). |
403 | vpn_requires_dedicated | vpn (your own VPN) on a plan without dedicated threads. | Use a proxy, or move to a dedicated plan (Own network). |
400 | vpn_not_available | vpn combined with proxy/proxy_rules, on an unsupported plan, or a live proxy swap on a VPN session. reason says which. | Send either vpn or a proxy, not both. |
400 | invalid_vpn_config | The VPN config can't be used: no saved VPN with that name, combined with vpn_tunnel, a missing or unsupported field or directive (named in reason), a private endpoint, or over 64 KB. | Fix the config, or check the name on Proxies → My VPNs. |
400 | vpn_connect_failed | Your VPN server didn't answer or refused the credentials, so no request got through it. | Check the server and credentials, then retry. |
402 | proxy_balance_exhausted | The launch (or a live swap) uses the cdpfleet residential proxy and your balance is used up. | Top up in the dashboard → Proxies. |
400 | The browser rejected a launch option — an unparseable proxy, an unknown Camoufox config property or an unsupported os. The message says which. | Fix the option; don't retry as is. | |
401 | missing_api_key / invalid_api_key | No key, or an unknown or revoked key. | Check x-api-key. |
402 | subscription_inactive | Your account has no active plan. | Check your plan in the dashboard. |
400 | cdp is not supported on this engine | "cdp": true on a browser without a CDP endpoint. The message lists the supported ones. | Use one of them, or connect to wsUrl (CDP & Puppeteer). |
403 | keep_alive_requires_dedicated | "keep_alive": true on a shared plan. | Use dedicated threads, or reconnect-free code. |
503 | keep_alive_unavailable | keep_alive isn't switched on for the fleet yet. | Launch without it for now. |
400 | invalid_keep_alive / invalid_record | keep_alive or record isn't true or false. | Send a boolean. |
400 | invalid_profile / profile_unsupported_engine | profile isn't a valid name or {id, mode}, or the browser doesn't support profiles yet. | See Persistent profiles. |
403 | profile_frozen | The profile is frozen: the account has been over its plan's profile limit for 30 days. | Upgrade to unfreeze it, or delete other profiles (profiles). |
403 | profile_limit | The account already has as many profiles as its plan allows (20 per shared thread, 30 per dedicated thread, at least 100). | Delete one with DELETE /v1/me/profiles/{name}, or add threads. |
404 | no_such_profile | A read-only launch of a profile that doesn't exist yet. | Launch it once in normal mode first. |
409 | profile_in_use | Another session is writing this profile. | Retry when it ends, or launch with "mode": "readonly". |
409 | profile_engine_mismatch / profile_version_downgrade | The profile belongs to another browser, or to a newer version of this one. | Use the browser (and channel) it was created with. |
503 | profile_restore_failed / profile_service_unavailable | The profile couldn't be loaded right now. | Retry. |
400 | invalid_cdp | cdp isn't true or false. | Send a boolean. |
400 | unsupported_option | A browser-process field the fleet doesn't take: args, extensions, executablePath, ignoreDefaultArgs, env, userDataDir, chromiumSandbox, devtools, downloadsPath or tracesDir. Browsers run with the fleet's own flags. | Remove the field; use the launch options and Playwright (init scripts, routing, headers) instead. |
400 | invalid_start_url | start_url isn't an http(s) URL of at most 2,048 characters. | Fix the URL (Launch interactive). |
400 | start_url_not_viewable / start_url_unsupported | start_url on a session nobody could watch (headless without live_view, or headless Firefox, Camoufox or WebKit). | Launch headful, or headless Chromium-based with "live_view": true. |
400 | start_url_not_supported | start_url on Rebrowser: its Playwright 1.52 server can't hand the opened page to your code. | Use another Chromium-based browser for Launch interactive. |
403 | profiles_disabled | A profile on the free Community plan. | Upgrade to a paid plan. |
503 | community_capacity_full | The Community capacity is full right now: Community-plan sessions and launches on the free Community proxy (any plan) share one cap. | Retry after Retry-After; on a paid plan, use your own proxy or the residential proxy for launches that must not wait. |
403 | engine_not_allowed | Your plan doesn't include this browser. | Use another browser or upgrade. |
404 | not_found | Unknown endpoint, e.g. a misspelled browser. | Check the path. |
413 | payload_too_large | The launch body is over 100 KB. | Send a smaller body; a long start_url or big config object is the usual cause. |
429 | rate_limited | Too many launches per second or minute for your plan. Includes rps_limit and rpm_limit. | Wait for Retry-After seconds. |
429 | threads_exceeded | This launch would exceed your threads. Includes threads, in_use and requested_weight. | Close a session or wait; Retry-After: 1. |
429 | daily_quota_exhausted | Shared threads: today's pool is used up. Includes the budget and usage. | Retry-After counts down to midnight UTC. |
429 | hourly_quota_exhausted | Shared threads: the last 60 minutes used 25% of your daily pool. Includes the budget and usage. | Wait; the window rolls forward continuously. Retry-After: 60. |
500 | The browser failed to start, e.g. the proxy is unreachable or Camoufox couldn't look up the proxy's location. | Check the proxy, then retry. | |
503 | shared_capacity_full | Shared threads: the shared fleet is full right now. Dedicated threads are never refused for this. | Retry after Retry-After (5 s). |
503 | fleet_unavailable / starting_up / route_unavailable | The fleet is momentarily full. | Retry with backoff. |
502 | route_rejected | The session couldn't be connected through the fleet's private network, so it was refused rather than exposed. Not billed. | Retry; a new launch goes to another server. |
503 | resi_unavailable | The cdpfleet residential proxy is momentarily unavailable on the server that took the launch. | Retry; it goes to another server. |
503 | version_unavailable | The requested version exists but no server with it is free right now, or, for a profile saved with a newer browser, no server runs at least that version (min_version; usually only while a new browser version is rolling out). Includes available, the majors you can pick. | Pick one from available, or retry the profile launch in a few minutes. |
Connecting
A WebSocket connect can fail with 401/403 (wrong key — only the key that launched the session may connect), 404 (the session has ended, or the 60-second connect window passed), 409 (the session already has a connection) or 502 {"error":"upstream_unreachable"} (the server running the browser didn't answer — rare). After a 502, launch a new session rather than reconnecting to the same wsUrl; the failed session isn't billed.
Limits
- Threads — concurrent sessions, weighted by type (see Sessions & billing).
- Launch rate — per second and per minute, set by your plan. Only launches that reach the fleet count; refused launches don't.
- Daily pool — shared threads only: threads × browser-minutes per day, resetting at midnight UTC.
- Rolling hour — shared threads only: 25% of the daily pool in any 60 minutes.
- Session length — 24 h at most (15 minutes on the free Community plan);
overall_timeoutis capped at it. - Connect window — 60 seconds from launch, except sessions launched with
start_url, which don't need a client. - Open pages per session — 50 on every plan, counting every tab, popup and context; memory usually runs out first with heavy pages. A page over the cap is closed at once on Chrome, Edge, Brave, Opera, Yandex and Chromium and the session goes on:
newPage()fails withpage_limit: this session already has 50 pages open (plan limit), so the new page was closed; the session continues. On the other browsers the session ends withpage_limit. - Network — a session reaches only public internet addresses. Loopback, private ranges (10/8, 172.16/12, 192.168/16, CGNAT), link-local and cloud-metadata addresses and the server's own addresses are refused — for pages, redirects,
context.request, DNS names that resolve to them, and as aproxy(a launch naming one gets400). - Memory per session — 2 GB on Community, 4 GB on shared, 6 GB on dedicated (headful sessions get 512 MB more for the display). Going over ends that session with
session_memory_limit; other sessions aren't affected. Need more?"memory": 2–4multiplies it, and the session's threads with it.
Known issues
net::ERR_NETWORK_CHANGEDon Chromium-based browsers (since 2026-11): a page load in Chrome, Chromium, Edge, Brave, Opera, Yandex, Whale, Patchright or Rebrowser can be aborted with this error when a VPN orvpn_tunnelsession starts or ends on the same server — Chromium cancels in-flight navigations whenever the server's network interfaces change. It is rare and short: retry the navigation (page.gotoagain) and it loads.