- The browser refuses a switch by printing
apostate: <reason>on stderr and exiting with status 1. The packages report that as a failed launch. - The Python package raises a subclass of
ApostateError. Python API lists the classes. - The Node package throws a subclass of
ApostateErrorwith acodestring. Node API lists the classes and codes.
--apostate-profile value, which holds the credential base64-encoded. Troubleshooting starts from symptoms instead of messages.
Error classes
Switches and seeds
A value above the host
Host mode with a persona or override
host inheritance disables every layer below it, so a platform persona cannot be applied at the same time (Node code APOSTATE_HOST_INHERITANCE_PERSONA).
Cause. --fingerprint=host (or off, false, 0, disable, disabled) together with --fingerprint-platform, --fingerprint-anchor or a per-field switch. Fix. Drop one of them.
A GPU string from another family
--fingerprint-gpu-renderer or --fingerprint-gpu-vendor names a model that is not in the GPU family this launch drew. Fix. Use a string from the list in the message, or add --fingerprint-anchor with the family that has the model. GPU models lists every family’s strings.
A screen that cannot hold the window
--fingerprint-screen-width or --fingerprint-screen-height is smaller than --window-size, or too small for the taskbar or menu bar. Fix. Pass a larger screen or a smaller window.
A seed the browser cannot use
fingerprint string must match [A-Za-z0-9][A-Za-z0-9._:-]* or fingerprint must be at most 512 bytes; the binary rejects a longer seed, Node with fingerprint must be a non-negative safe integer or a stable non-empty string.
Cause. The seed is empty, over 512 bytes, or contains a space or a character outside ASCII. Fix. Use letters, digits, ., _, : and -, starting with a letter or digit, such as shop-account-1.
An unknown or misspelt switch
ConfigurationError. Node throws ProfileResolutionError with code APOSTATE_MISSPELLED_FINGERPRINT_SWITCH or APOSTATE_UNKNOWN_FINGERPRINT_SWITCH.
Cause. A switch in args starts with --fingerprint but is not one the browser reads, or is within two edits of one. The browser would ignore it without a word. Fix. Use the spelling from Switches.
Noise turned off with a value
--fingerprint-noise with false, 0, no, off, disable or disabled. Fix. Leave the switch out. Noise is off by default.
An unknown GPU family or platform
These are logged, not refused. The launch goes ahead.windows, macos or linux.
Launch options
A persistent profile passed to launch()
launchPersistentContext(userDataDir, options), with code APOSTATE_USER_DATA_DIR_ON_LAUNCH, or APOSTATE_USER_DATA_DIR_SWITCH_IN_ARGS for --user-data-dir in args.
Cause. user_data_dir or userDataDir passed to launch(), or --user-data-dir in args. Fix. Call launch_persistent_context(path, ...) or launchPersistentContext(path, options).
A timezone that is not an IANA zone
From 0.4.4 both packages refuse the name before launch. Python raisesConfigurationError, and Node throws RangeError:
timezone names a zone that the host’s tz database (Python) or Intl (Node) does not know, such as a typo or an abbreviation like CEST. In 0.4.3 the name went into TZ, and a page’s Intl.DateTimeFormat().resolvedOptions().timeZone read undefined. Fix. Pass an IANA name, such as Europe/Berlin or America/New_York.
A proxy switch in args (Node)
APOSTATE_PROXY_SWITCH_IN_ARGS. Fix. Pass the proxy URL as the proxy option.
Options passed to new_page()
TypeError with the same text in Node’s names, newPage() and newContext(options).
Cause. Page options such as viewport given to the browser’s new_page(). Fix. Pass them to launch(), which gives them to the profile’s context, or open an off-the-record context with new_context(...).
A profile and a seed together
APOSTATE_ENVELOPE_SEED_CONFLICT.
Cause. A profile that describes a device, and --fingerprint in args. Fix. Use one or the other. A profile you write replaces composition.
A profile that does not match the schema
profile.cpu.cores is not part of the schema.
Cause. An unknown key, a wrong type or a value out of range. Fix. Check the field in Profile schema.
A profile name instead of a path
APOSTATE_CATALOGUE_PROFILE_IDS_RETIRED.
Cause. profile is a string that does not look like a path. A string counts as a path when it ends in .json, contains a slash, starts with . or is absolute. Fix. Pass the file’s path, such as ./profiles/desktop.json, or the profile as a dict or object. To pick a persona, use fingerprint_platform.
No driver installed
npm install patchright and throws BrowserLaunchError.
Cause. Patchright is missing or broken, which means a partial install. Fix. Reinstall it as the message says. Neither package needs playwright install.
Installing the browser
Installation covers the cache, mirrors and offline installs.Nothing to download
github.com, or point APOSTATE_BINARY at a browser you unpacked yourself.
A download that does not match
SHA-256 mismatch for apostate-152.0.7977.83-linux-x64.tar.zst.
Cause. The download was cut short or corrupted, or a mirror in APOSTATE_DOWNLOAD_BASE_URL serves other bytes. Fix. Run apostate install again, and check the mirror.
A host with no build
No zstd on Linux
.tar.zst. Python before 3.14 and Node before 22.15 cannot decompress zstd on their own. Fix. Install zstd (apt install zstd), or use the newer runtime.
GNU tar and a zip archive (Node on Windows)
tar, and GNU tar cannot read zip. Fix. Put Windows’ own tar.exe (bsdtar) first on PATH.
Downloading through a proxy (Node)
BinaryDownloadError, code BINARY_DOWNLOAD_FAILED.
Cause. A launch with proxy on a machine without the browser. The Node package does not download through the proxy. Fix. Run npx apostate install once without the proxy, or pass a download function that fetches through it.
A named browser that is not there
the configured path for executablePath and binaryPath.
Cause. APOSTATE_BINARY, binary_path or executablePath names a path with no browser. Fix. Name the executable, the .app bundle or the directory the archive unpacks to, or unset the variable.
Running
Xvfb is missing
headless: true.
Cause. A launch with headless off on a Linux host with no display. The package starts Xvfb for it, and Xvfb is not installed. Fix. apt install xvfb, or launch headless. Linux servers has the details.
The GeoIP lookup failed
A warning, not an error. The launch goes ahead. From 0.4.4 the Python package prints:[Apostate], with Node’s own connection error, such as connect ECONNREFUSED 127.0.0.1:9. Both packages also put the warning in the launch’s diagnostics: apostate_diagnostics["warnings"] in Python from 0.4.4, apostateDiagnostics.warnings in Node. A similar warning says when the lookup answered without a country or a timezone.
In 0.4.3 the second half of the message says the launch keeps the host’s own locale. That is wrong. The persona uses en-US, as the 0.4.4 text says.
Cause. The lookup could not reach any endpoint, or the proxy refused the connection. The persona then uses en-US and the host’s timezone, which behind a proxy is not the exit’s. Fix. Check the proxy, or pass locale and timezone yourself. Locale and timezone covers the lookup.
The browser did not start
--apostate-profile value in it reads --apostate-profile=<redacted>. Fix. Run the same switches as apostate run -- <switches> --fingerprint-explain to see the browser’s own apostate: message.