Hermes Agent

browser

Hermes Browser Automation Not Working? Fix CDP, Profile, and Timeout Failures

·Hermes browser automation not workingbrowserautomationtroubleshootingcdpdockeroperations

Fix Hermes browser automation when browser_exec hangs, Chrome CDP goes stale, real-profile login fails, Docker blocks localhost, or websites trigger anti-bot checks.

Hermes Agent browser automation is built for pages that must be rendered and operated, not just downloaded. It can navigate dynamic sites, read accessibility snapshots, click controls, type into forms, inspect JavaScript errors, capture screenshots, and verify what a user actually sees. The difficult part is rarely the first click. It is choosing the right browser backend and diagnosing failures without confusing a provider outage, an expired session, Docker networking, anti-bot friction, or page JavaScript.

Quick answer#

If Hermes browser automation is not working, identify both the driver and the browser source before changing providers. On current installs, Browser Use CLI 3.0 is the default driver when it is runnable and exposes one browser_exec tool; otherwise Hermes falls back to its built-in browser tools. Run hermes doctor, confirm the browser toolset is enabled, and use /browser use status in the interactive CLI to see the effective mode. Then test one public page and one simple interaction. A missing browser_exec can mean the CLI is unavailable or terminal access is disabled; a 401 or 403 usually points to credentials or site policy; a 502 after an older cloud session may mean the remote session expired; connection refused on 127.0.0.1 inside Docker usually means the service is not in that container; a CAPTCHA or Cloudflare challenge is an anti-bot boundary, not proof that Hermes is broken. Use web search or extraction provider guidance when you only need text, and use browser automation when the task requires rendering, login state, clicks, screenshots, console inspection, or visual QA.

For setup rather than diagnosis, follow the browser automation configuration guide. For a managed agent that should stay available from browser or phone without local browser and VPS maintenance, compare FlyHermes pricing with the self-hosted versus hosted guide.

Choose the browser backend before debugging it#

Hermes currently supports several browser paths. They solve different problems:

  • Browserbase cloud is a managed Chromium browser with cloud sessions, proxy options, and anti-bot tooling.
  • Browser Use mode is the current default driver when Browser Use CLI 3.0 is runnable. It exposes browser_exec, executes model-written Python, supports named concurrent sessions, and can drive local Chrome or a configured cloud browser source.
  • Browser Use cloud is one managed browser source. Authenticate it with browser-use auth login or BROWSER_USE_API_KEY. Browserbase still takes priority when both legacy cloud credentials are present.
  • Firecrawl cloud browser combines browser sessions with scraping-oriented infrastructure.
  • Camofox local runs a Firefox-based anti-detection browser you operate yourself. CAMOFOX_URL routes browser tools through that service.
  • Lightpanda local engine is a machine-first headless browser with fast startup and lower memory use; Hermes automatically falls back to Chrome for actions Lightpanda does not support.
  • Local Chromium-family CDP attaches Hermes to Chrome, Brave, Chromium, or Edge through the interactive CLI command /browser connect.
  • Local agent-browser remains the built-in no-cloud fallback when no cloud credentials or CDP connection are selected.
  • Nous Tool Gateway can provide browser tooling to eligible subscribers without separate browser-provider keys.

Start with Hermes browser automation setup if you have not selected one. Do not configure three providers at once and then guess which one answered. Prove one backend first, record its effective configuration, and add alternatives only when you understand their priority.

Check the driver before the provider#

Current Hermes browser setup has two layers:

  1. The driver is either Browser Use mode (browser_exec) or the built-in browser_navigate, browser_snapshot, browser_click, and related tools.
  2. The browser source is local Chrome, Nous Tool Gateway, Browserbase, Browser Use cloud, Firecrawl, Camofox, Lightpanda, or local Chromium.

Browser Use mode is selected automatically when browser.backend is unset and the Browser Use CLI can run. It requires terminal access because it executes model-written Python locally. A locked-down messaging profile without terminal tools keeps the built-in browser toolset. Named calls such as session=checkout-qa isolate the harness daemon and cloud browser so parallel agents or simultaneous chats do not overwrite one shared connection.

Use these interactive CLI controls:

/browser use status
/browser use off
/browser use on

Turn Browser Use mode off temporarily when you need to compare the same failure against the built-in tools. Do not mistake a driver failure for a Browserbase, Firecrawl, or local-Chrome failure.

The seven browser failure classes#

1. The browser never launches#

Symptoms include a missing browser tool, executable-not-found errors, Playwright/Chromium launch failures, or a session that dies before navigation.

Check:

hermes doctor
hermes tools list
hermes setup tools

Confirm Browser Automation is enabled. A new tool configuration takes effect in a new Hermes session. If browser_exec is missing, run /browser use status: the Browser Use CLI may be unavailable, or the current platform may not expose terminal access. On a local backend, verify the selected engine, Browser Use CLI or agent-browser, and Chromium are available in the environment that actually runs Hermes. A shell may have a full PATH while a scheduled service, Desktop process, or container does not.

In Docker, browser processes also need enough shared memory. If the browser crashes under load, verify the container's /dev/shm allocation and the current official Docker guidance before adding random launch flags.

2. A cloud session expired or returns 502#

Cloud browser sessions have provider and inactivity limits. A CDP URL that worked earlier can become invalid after its session expires. Recent Hermes support evidence included Browser Use 502 failures caused by reconnecting to a managed session after its timeout; current releases retire expired sessions and create a fresh one.

Use this recovery sequence:

  1. Confirm the failure occurs on a new, harmless public URL.
  2. End the stale browser task and start a fresh session instead of retrying the same CDP endpoint forever.
  3. Update Hermes if the install predates the expired-session cleanup.
  4. Check the provider dashboard or API status for session expiry, quota, and regional failures.
  5. Reduce the job into shorter checkpoints if it routinely exceeds the provider TTL.

Do not increase every timeout blindly. A dead remote session does not become healthy because the agent waits longer.

3. Localhost works on the host but fails in Docker#

127.0.0.1 always means "this network namespace." Inside a Hermes container, http://127.0.0.1:8888 points back into the Hermes container, not to SearXNG, a browser server, or an app running on the host.

Use the service name on a shared Compose network, or a documented host alias such as host.docker.internal where supported. For Camofox in Docker, Hermes has explicit loopback-rewrite settings for page navigation. Keep CAMOFOX_URL pointed at the control API and configure page URL rewriting separately.

This boundary also matters for search. SearXNG is a web-search backend, not a browser backend, and it is search-only. If SEARXNG_URL points to an unreachable container-local address, selecting SearXNG does not automatically make Brave, Firecrawl, or another provider a runtime fallback. Use the provider and fallback guide to configure fallback behavior deliberately.

4. A site blocks automation#

CAPTCHAs, Cloudflare challenges, login reauthentication, device checks, and rate limits are site-level controls. They may appear even when the browser itself is healthy.

A safe browser task should:

  • stop and capture a screenshot when a human verification challenge appears;
  • avoid repeatedly hammering the same blocked route;
  • use a permitted API or export when the site offers one;
  • preserve terms-of-service and account boundaries;
  • never claim success from an error-page screenshot or challenge HTML.

A cloud or anti-detection browser may improve compatibility. It does not grant permission to bypass access controls.

5. Navigation works but the page action fails#

Hermes operates from accessibility snapshots. Interactive elements receive references such as @e1 and @e2. Those references belong to the current snapshot. After navigation, a modal, or a major DOM update, take a fresh snapshot before clicking again.

Use this evidence loop:

  1. Navigate.
  2. Take a compact snapshot.
  3. Click or type using the current element reference.
  4. Take a new snapshot after the page changes.
  5. Inspect the console if the visible result is wrong.
  6. Capture a screenshot when layout or visual state matters.

Native JavaScript dialogs need an explicit policy. must_respond pauses for a decision; auto_dismiss or auto_accept handles the dialog automatically. Pick the policy based on the workflow rather than letting a hidden alert stall the entire run.

6. The page looks fine but JavaScript failed silently#

Accessibility text cannot prove that a React app, checkout, analytics event, or background request completed. Use browser console inspection for uncaught exceptions and failed requests. For QA, require a visible result plus a technical result: for example, confirmation text and no relevant console error, or a created record and a successful network response.

For layout work, verify desktop and phone widths. Check that document.body.scrollWidth <= window.innerWidth, headings are visibly styled, lists render, code is readable, and the mobile header does not consume the page. The Hermes Web UI guide is a good example of why browser QA must verify the rendered control surface rather than only an HTTP 200.

7. Search, extraction, and browser tools are being mixed up#

Use the cheapest tool that can prove the result:

  • web_search discovers sources.
  • web_extract reads plain pages and documents.
  • Browser tools operate dynamic pages, authenticated state, forms, dialogs, screenshots, and visual layouts.

A web-search provider failure is not automatically a browser failure. A browser can open a page while search is out of credits, and search can return results while a target site blocks automation. Diagnose each rail independently.

Fix browser_exec hangs after Chrome restarts#

A seven-minute browser_exec timeout is a different failure from a website CAPTCHA. Recent v0.21 reports show a specific real-profile failure: Chrome exits or is replaced, but a browser-harness or agent-browser daemon remains alive with the old Chrome DevTools Protocol endpoint. Its socket can still look healthy while every new command waits on a browser that no longer exists.

Recognize the stale-CDP pattern#

Suspect a stale browser transport when all of these are true:

  • browser.use_real_profile is enabled;
  • the first browser run worked, then Chrome, the gateway, or the host restarted;
  • multiple unrelated public URLs now hang for the same full timeout;
  • a fresh web extraction or search still works;
  • logs mention an old 127.0.0.1:<port> CDP endpoint, connection refused, All CDP discovery methods failed, or no browser progress after connecting to the harness socket.

Do not diagnose this as anti-bot blocking. A site challenge appears after navigation and is usually visible in a snapshot or screenshot. A stale CDP endpoint prevents the browser from reaching even https://example.com.

Recover without deleting browser identity#

  1. Run /browser use status and record the active driver, browser source, real-profile setting, and named session.
  2. Test a harmless public page in a fresh named browser_exec session. If it works, the original named session is stale; do not reset every profile.
  3. Update Hermes before applying process-level workarounds. Browser and real-profile fixes have changed quickly, including the Chrome 136+ profile-copy path.
  4. Stop the affected browser task or gateway cleanly. Confirm the real-profile Chrome process and its harness daemon actually exited before restarting.
  5. If a stale daemon remains, identify the exact process before terminating it:
pgrep -af 'browser_harness.daemon|agent-browser'

Do not use a broad pkill chrome: that can close unrelated browsers and lose unsaved work. Do not delete ~/.hermes, the source browser profile, or copied browser-auth state as a first step.

  1. Start a fresh Hermes session, run one https://example.com smoke test, and require the final URL, H1, screenshot, and console result.
  2. Only after transport works should you retry the original site and classify login, CAPTCHA, policy, or action failures.

Separate three real-profile failures#

  • Stale endpoint after a crash or restart: the daemon points to a dead ephemeral CDP port. A fresh named session or clean browser-daemon restart can isolate it.
  • Chrome 136+ remote-debugging consent: Chrome may require a visible one-time approval before attaching to an existing foreground profile. A headless flow cannot click a visible consent prompt. Update first and test the current profile-copy implementation rather than recycling old --remote-debugging-port advice.
  • Wrong profile selected: transport succeeds, but the expected login is absent. Pin the intended profile, verify identity read-only, and keep the agent profile separate from everyday browsing.

The browser setup guide covers real-profile and CDP configuration. The Hermes update guide provides the safe upgrade path, and the monitoring guide shows how to detect a wedged browser before a scheduled workflow silently misses delivery.

Browser reliability acceptance test#

Before trusting an authenticated or scheduled browser workflow, prove recovery—not only the happy path:

  1. Run a public navigation and capture URL, title, H1, screenshot, and console output.
  2. Run a read-only page using the dedicated signed-in profile and confirm the intended account without exposing credentials.
  3. Restart only the browser process or test runtime.
  4. Repeat the public navigation in the same workflow and verify it does not reuse a dead endpoint.
  5. Run a fresh named session and verify it is isolated from the first session.
  6. Trigger the real scheduled job once and confirm the artifact reaches the exact Telegram topic, Discord channel, Slack thread, or file destination.
  7. Record elapsed time and fail the monitor well before the global tool timeout if no browser progress appears.

For a self-hosted system, the operator owns this recovery test, daemon cleanup, profile security, updates, and delivery. If browser/mobile access matters but maintaining the runtime does not, compare the operational boundary in the self-hosted versus hosted responsibility matrix and the managed path on FlyHermes pricing.

A copy-paste browser smoke test#

Give Hermes a bounded test before trusting it with a production account:

Open https://example.com.
Confirm the page title and visible H1.
Take an accessibility snapshot.
Inspect the browser console for JavaScript errors.
Capture a screenshot.
Report the URL, title, H1, console result, and screenshot path.
Do not log in, submit a form, or navigate away.

Then test one interaction on a disposable page. If you expect concurrent work, repeat it with two different named Browser Use sessions and confirm they do not share tabs or state. Only after both pass should you attach a logged-in profile or schedule an unattended workflow.

Logged-in sessions and profile safety#

A persistent browser profile is credential-bearing state. Treat it like an API key store:

  • keep it inside the intended Hermes profile;
  • avoid sharing one browser identity across unrelated trust levels;
  • use a dedicated debugging profile for CDP when possible;
  • do not expose a remote-debugging port publicly;
  • coordinate tab ownership if another app and Hermes share a Camofox identity;
  • clear server-side state when you intentionally reset a persistent Camofox user.

For local Chrome or Brave, /browser connect is an interactive CLI command. It is not a Telegram, Discord, gateway, or WebUI command. Run Hermes in a terminal and issue it there. On WSL2 controlling Windows Chrome, current Hermes documentation recommends a Windows-side browser MCP bridge when direct CDP reachability is unreliable.

Production checklist for browser agents#

Before scheduling the workflow with Hermes cron jobs, verify:

  • the chosen browser provider is explicit;
  • the runtime environment has the same keys and PATH as the successful test;
  • session TTL is longer than the bounded job or the job can recover with a fresh session;
  • private/localhost routing is understood;
  • login state is scoped and recoverable;
  • anti-bot challenges fail closed;
  • screenshots and console errors are saved as evidence;
  • retries are bounded and do not repeat writes;
  • the final result is checked in the real destination;
  • a human owns provider quota, credential rotation, and incident response.

Use Hermes security hardening before giving a browser access to production accounts. Use Telegram or Discord for alerts only after you have tested the exact channel delivery path.

Self-hosted browser automation or managed agent?#

Self-hosting gives you control over the browser, profiles, network, and logs. It also makes you responsible for Chromium dependencies, Docker networking, session cleanup, provider keys, challenge handling, scheduled execution, and recovery when a site changes.

Choose self-hosting when browser identity, custom networking, local applications, or infrastructure control are the point. Choose FlyHermes when the desired outcome is an available agent you can reach from browser or phone, without turning browser and VPS operations into a second job. The Hermes pricing and cost path helps compare the operator time as well as server and provider spend.

Final diagnostic rule#

Do not ask "is browser automation broken?" Ask which layer failed: tool enablement, browser launch, provider session, network address, site policy, page interaction, JavaScript, or final delivery. That classification turns random retries into a reproducible fix.

Fix real-profile browsing that opens signed out#

Real-profile browsing is different from /browser connect. It copies the selected Chromium profile into a Hermes-managed snapshot, refreshes the authentication files, and launches the user's real Chromium binary against that copy. Your normal browser profile is not opened directly. This is useful when a browser task needs existing login state but should not take over your everyday tabs.

Enable it explicitly:

hermes update
hermes config set browser.use_real_profile true

Then start a new Hermes session and ask the agent to open a local browser session. In Browser Use mode, that means a browser_exec call with local=true. Test one harmless authenticated page before authorizing any message, upload, purchase, or account change.

macOS: cookies exist, but every site opens signed out#

This was a real Keychain boundary, not an empty-cookie problem. Earlier launch paths could attach flags that made copied macOS Keychain-encrypted cookies unreadable. Current upstream Hermes launches the signed browser binary directly, waits for its DevToolsActivePort, and then attaches over CDP. It also avoids an unbounded SQLite wait while Chrome owns authentication databases and normalizes the copied profile so Chromium opens the mirrored identity instead of a missing source directory.

The practical recovery sequence is:

  1. Update Hermes to a build containing the merged macOS real-profile fix.
  2. Start a new real-profile browser session; the snapshot refreshes automatically, so deleting it should not be the first step.
  3. Open a read-only page that normally shows your signed-in identity.
  4. If it is still signed out, confirm which source profile Hermes selected before inspecting cookie counts or changing Keychain settings.
  5. Do not paste cookies, profile databases, OAuth tokens, or Keychain values into a support thread.

Pin the intended Chrome profile#

On a machine with work and personal Chromium profiles, following profile.last_used can select the wrong identity. Pin the source directory in ~/.hermes/config.yaml:

browser:
  use_real_profile: true
  real_profile_pin: "Profile 2"

Use the Chromium profile directory name, such as Default or Profile 2, not the visible person or account label. A missing pin fails closed instead of silently falling back to whichever profile was used last. That is safer than debugging a task after it has already acted as the wrong principal.

Security check after upgrading#

A real-profile snapshot contains session credentials. Current upstream Hermes reconciles snapshot files to owner-only permissions and heals older lax snapshots on the next refresh. Keep HERMES_HOME private, do not mount the snapshot into unrelated containers, and do not expose it through a web server or backup that lacks credential-level protection. The Hermes security guardrails should govern side effects even when authentication works.

Real profile, live CDP, or isolated browser?#

Choose the smallest authentication surface that can complete the task:

  • Real-profile snapshot: use when a local task needs existing Chromium login state without controlling the everyday profile directly.
  • /browser connect: use from the interactive CLI when you deliberately want Hermes attached to a dedicated visible Chromium process over CDP. Chrome 136+ requires a non-default --user-data-dir for remote debugging.
  • Isolated local or cloud browser: use for public research, fresh logins, repeatable QA, or work that should not inherit personal identity.
  • Extraction or API: use when rendered state and browser authentication are unnecessary.

For exact setup paths, use the browser automation configuration guide. For long-running checks, pair the chosen identity with AI agent monitoring and cron delivery verification. If keeping browser, gateway, VPS, update, and credential state healthy is not the job you want, compare the managed FlyHermes path with self-hosting Hermes.

Real-profile failure matrix#

  • Snapshot is created, but sites are signed out on macOS: update first, then start a new session; do not assume the cookies are absent.
  • The wrong Google/work account appears: set browser.real_profile_pin to the intended directory and retry read-only.
  • Launch hangs while normal Chrome is open: update; the current copy path bounds or avoids the live SQLite lock problem.
  • A pinned profile does not exist: correct or remove the pin. Hermes should fail closed rather than use another identity.
  • It works locally but not in Docker: the host's Chromium profile and OS keychain are not automatically available inside the container. Use a host-local browser path or an isolated authenticated backend instead of copying secrets into the image.
  • It works in CLI but not Telegram/Web UI: interactive /browser connect is CLI-only, and Browser Use mode requires terminal access. Check the actual toolset and browser lane for that surface.
  • The page is logged in, but the action fails: refresh the accessibility snapshot, inspect console/network state, and verify the final business outcome instead of treating authentication as success.

v0.21 can drive the Desktop browser#

The Desktop browser is now an action surface: Hermes can navigate, click, and read inside it. The v0.21 release guide covers the shipped change; the source-choice and troubleshooting rules here still apply to authentication, anti-bot barriers, CDP, Docker, and verification.

Frequently Asked Questions

Why do I see browser_exec instead of browser_navigate?

Current Hermes installs default to Browser Use mode when Browser Use CLI 3.0 is runnable and terminal access is available. That mode exposes one browser_exec tool. Run /browser use status to confirm it, or /browser use off to compare the same task with the built-in browser tools.

Why is browser_exec missing?

Browser Use mode needs a runnable Browser Use CLI and terminal tool access because it executes model-written Python locally. Locked-down messaging sessions keep the built-in browser tools. Check /browser use status from the interactive CLI and verify the active profile toolsets.

Can parallel agents use separate browser sessions?

Yes. browser_exec accepts a session name. Each name receives an isolated harness daemon and, on cloud backends, a separate browser. Use explicit names for parallel subagents or simultaneous chats; the unnamed default is intended for one-at-a-time work.

Does Hermes support Lightpanda?

Yes. Lightpanda is a local machine-first headless engine. Hermes can use its fast, low-memory path and automatically fall back to Chrome for actions Lightpanda does not support.

Why does a cloud browser return 502 after being idle?

The managed session or its CDP endpoint may have expired. Start a fresh browser task, test one public URL, check provider status and quota, and avoid retrying the same dead endpoint indefinitely.

Why can Hermes not reach localhost from Docker?

Inside a container, 127.0.0.1 points to that container. Use a shared-network service name, a supported host alias, or Hermes hybrid local routing rather than sending a private URL to a cloud browser.

How do I connect Hermes to my own Chrome or Brave browser?

Start Hermes in an interactive terminal and run /browser connect, then verify with /browser status. This is a CLI command, not a Telegram, Discord, or Web UI slash command.

How should Hermes handle CAPTCHA and protected flows?

Use only authorized access and provider capabilities. Capture the blocked state and pause for a person when required. Never infer success from challenge HTML or bypass a site’s access rules.

How do I use my real Chrome profile with Hermes?

Enable browser.use_real_profile, update Hermes, start a new session, and request a local browser run. Hermes snapshots the selected Chromium profile rather than opening your everyday profile directly. Test a harmless signed-in page before approving side effects.

Why does Hermes real-profile browsing open signed out on macOS?

Older launch paths could make copied Keychain-encrypted cookies unreadable. Update to a current build containing the merged macOS fix, then start a new real-profile session so Hermes refreshes the snapshot automatically.

How do I stop Hermes from choosing the wrong Chrome profile?

Set browser.real_profile_pin to the Chromium directory name, such as Default or Profile 2. A missing pinned directory fails closed instead of silently using the last-opened profile.

Why does browser_exec hang after Chrome or the gateway restarts?

A surviving browser-harness or agent-browser daemon can still point to the previous Chrome CDP port. Confirm the pattern on a harmless public URL, try a fresh named session, update Hermes, then cleanly restart only the affected browser daemon. Do not delete the source profile or kill every Chrome process.

Is a browser_exec timeout the same as a CAPTCHA?

No. A CAPTCHA or site challenge happens after navigation and is usually visible. A stale CDP or harness failure prevents unrelated public pages from loading at all. Prove transport on example.com before debugging the target site.

How should I test browser recovery before scheduling a job?

Run a public smoke test, verify the intended read-only login, restart the browser runtime, repeat the test, try an isolated named session, and trigger the real schedule once with screenshot, console, artifact, and exact delivery evidence.

FlyHermes (Managed Cloud)

Deploy in 60 seconds. API costs included. Cancel anytime.

Deploy faster with FlyHermes →

Self-Host (Open Source)

Full control. MIT licensed. Run on your own infrastructure.

View install guide →

Keep reading

Related Hermes Agent guides