If Selenium stops at “Launching Firefox…”, first preserve a geckodriver trace log, then verify the Firefox executable, geckodriver executable, and temporary-profile directory. The most important distinction is whether Firefox is a native install or a Snap/Flatpak package: sandboxed Firefox may not be able to read the profile directory that geckodriver creates, causing startup to wait indefinitely.
What the stall means
Before a test can open a page, Selenium starts the separate geckodriver WebDriver server, launches Firefox, creates or copies a profile, and completes the Marionette handshake. “Launching Firefox…” means one of those startup exchanges has not completed; it does not identify the failing component by itself.
Mozilla’s Firefox Source Docs says trace-level output is vital when debugging geckodriver or Firefox. Trace output includes WebDriver requests, protocol traffic, and Marionette messages, so it shows the last successful step instead of leaving you to guess.
Fix it in the right order
- Capture evidence. Enable trace logging and preserve the complete output, especially in CI.
- Identify both executables. Confirm which Firefox binary and which geckodriver Selenium is actually using.
- Test a clean temporary profile. A custom, locked, oversized, or inaccessible profile can hide the original failure.
- Check package confinement. Snap and Flatpak can give Firefox and geckodriver different views of the filesystem.
- Check versions and PATH. Make sure Selenium, Firefox, and geckodriver are intended to work together.
- Add headless mode last. Headless removes display-server requirements but cannot repair a bad binary path or profile permission.
1. Turn on geckodriver trace logging
Run geckodriver directly
Start the driver with maximum verbosity while reproducing the failure:
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
geckodriver -vv 2> geckodriver.log
Leave that process running, execute the Selenium test in another terminal, and inspect the final lines in geckodriver.log. In a CI job, redirect standard error to an artifact so a timeout does not discard the evidence.
Enable logging from Selenium (Python)
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
options = Options()
options.log.level = "trace"
# Add this only after a normal launch works:
# options.add_argument("-headless")
service = Service(log_output="geckodriver.log")
driver = webdriver.Firefox(service=service, options=options)
try:
driver.get("https://example.com")
finally:
driver.quit()
Use the equivalent Firefox service log setting in your language binding. The useful clue is normally the last completed action: executable detection, profile creation, port connection, or Marionette communication.
2. Verify the Firefox executable
Selenium can be told explicitly which Firefox binary to launch. First find the real executable rather than assuming the command on your PATH is the browser itself:
- On a native Linux installation, inspect the path returned by your package manager or
which firefox. - On Windows and macOS, use the installed application’s executable, not a shortcut or shell wrapper.
- On Ubuntu Snap,
/snap/bin/firefoxis a launcher. Mozilla documents that supplying it as the binary path can produce “binary is not a Firefox executable”.
Set an explicit binary when multiple installations exist:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.binary_location = "/path/to/the/real/firefox"
driver = webdriver.Firefox(options=options)
Do not mix a native Firefox binary with a driver confined for Snap, or a Snap launcher with an unrelated native geckodriver. The pair must be able to inspect and start one another.
3. Verify geckodriver discovery and compatibility
Geckodriver is a separate WebDriver server. Selenium normally finds it through PATH, unless you configure a service with an explicit path. Check the selected executable in the same user and CI environment that runs the test:
Rank #2
which geckodriver
geckodriver --version
which firefox
firefox --version
If more than one result is possible, configure the intended path explicitly:
from selenium.webdriver.firefox.service import Service
service = Service(executable_path="/absolute/path/to/geckodriver")
Mozilla’s usage documentation requires Selenium 3.11 or newer for geckodriver. Selenium’s current Firefox guidance recommends the latest geckodriver and states that Selenium 4 requires Firefox 78 or newer. In practice, update the Selenium binding, Firefox, and geckodriver together rather than replacing only one component.
4. Fix Snap and Flatpak profile visibility
A startup hang is frequently a filesystem-visibility problem with containerized Firefox. Selenium asks geckodriver to create a temporary profile; Firefox may run inside a sandbox that cannot see that directory, while geckodriver runs outside it. Firefox then never completes startup.
Ubuntu Snap Firefox
Use the Snap-confined geckodriver so both processes share the expected confinement:
/snap/bin/geckodriver -vv 2> geckodriver.log
Alternatively, install a non-container Firefox release and its matching geckodriver. Do not pass /snap/bin/firefox as though it were the underlying browser executable; use the documented full binary path only with the matching confined driver.
Flatpak or another sandbox
Either run the compatible driver inside the same sandbox or provide a profile root that both processes can access. Set TMPDIR before starting the test, or use geckodriver’s --profile-root option:
Rank #3
mkdir -p "$HOME/selenium-tmp"
chmod 700 "$HOME/selenium-tmp"
export TMPDIR="$HOME/selenium-tmp"
geckodriver --profile-root "$HOME/selenium-tmp" -vv
The directory must be writable by the test user and visible from the Firefox sandbox. A directory that exists for the host but not inside the container does not solve the problem.
5. Eliminate custom-profile variables
Start with Selenium’s anonymous temporary profile. If you pass a custom profile, Selenium copies it into a new temporary directory; extensions, file locks, a large cache, or permissions inherited from another user can all obscure the real cause.
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options() # no profile supplied
# options.add_argument("-headless") # add after baseline launch succeeds
driver = webdriver.Firefox(options=options)
try:
driver.get("https://example.com")
finally:
driver.quit()
Once this launches, add preferences, certificates, extensions, and a custom profile one change at a time. If the stall returns, the last change identifies the suspect.
6. Add headless mode only after a normal launch
Firefox accepts the -headless argument, which is useful on CI hosts without a display server:
options.add_argument("-headless")
First prove that the same executable and clean profile launch without headless mode when a local display is available. Then enable headless mode in CI. A headless flag cannot fix an inaccessible profile, an incorrect binary, or an incompatible driver.
Choose the remedy by installation type
| Environment | Best baseline | What to verify | Typical recovery |
|---|---|---|---|
| Native Firefox | Clean temporary profile | PATH, executable permissions, versions | Explicit binary and geckodriver paths; update components |
| Ubuntu Snap | Matching confined processes | Firefox and driver confinement | Use /snap/bin/geckodriver, or switch both to native packages |
| Flatpak | Shared accessible profile root | Sandbox filesystem visibility | Use a compatible in-sandbox driver or set TMPDIR/--profile-root |
| CI headless | Prove a clean non-headless launch first | Display variables, writable temp directory | Add -headless after the baseline passes |
Troubleshooting by symptom
The log says “binary is not a Firefox executable”
The configured path is probably a wrapper such as /snap/bin/firefox, not the browser binary geckodriver expects. Remove the override, use the actual executable, or use the matching Snap-confined geckodriver.
The log stops while creating or copying a profile
Check ownership, write permission, free space, and sandbox visibility for the temporary directory. Remove the custom profile, set a known-writable TMPDIR, and retry with --profile-root.
The log shows a port or Marionette timeout
Confirm that the selected Firefox binary can run as the test user and that the driver is not from a different installation. Run both version commands, inspect the trace immediately before the timeout, and test the clean-profile example.
Recommended Free Tools
It works locally but hangs in CI
Compare the CI user, PATH, package type, temporary-directory mount, and display environment with the local machine. Preserve the trace log as a build artifact. Add headless mode only after those values are known to be correct.
A custom profile works once and then hangs
Do not reuse a profile directory concurrently. Close every Firefox process, return to Selenium’s temporary profile, and reintroduce extensions and preferences individually.
It starts, but the first page load fails
Separate browser startup from navigation. Keep the startup trace, then diagnose DNS, proxy, certificates, or application errors independently; changing profile roots will not repair a page-level network failure.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is a rendered image or PDF rather than an interactive Selenium session, ScreenshotNeo provides a single HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11cURL (options and API details: ScreenshotNeo documentation):
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Is this always a Firefox bug?
No. The same symptom can come from Selenium selecting the wrong executable, geckodriver incompatibility, or a profile directory that Firefox cannot access.
Should I delete every Firefox profile?
No. First test Selenium’s temporary profile. Delete or alter a persistent profile only when trace evidence points to that profile.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Can increasing the Selenium timeout fix the stall?
It may make the failure slower, but it does not correct a blocked filesystem, wrong binary, or incompatible driver. Capture trace output before changing timeouts.
Does ScreenshotNeo replace Selenium?
Only for capture tasks. Selenium remains the appropriate choice when a test must interact with a browser, click through an application, or assert behavior between steps.
Frequently Asked Questions
Which component should I update first?
Update Selenium, Firefox, and geckodriver as a compatible set, then rerun the clean-profile test with trace logging.
Where should CI logs be stored?
Redirect geckodriver’s trace output to a file and publish that file as a CI artifact so timeout cleanup does not erase the final startup exchange.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsQuick 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.

