What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

If Selenium hangs while starting Firefox on Ubuntu 22.04 or later, first check whether Firefox is the Snap package and which geckodriver executable your script launches. A documented cause is that Snap’s filesystem isolation can prevent Firefox and geckodriver from accessing the same temporary profile. For Ubuntu’s Snap Firefox, Mozilla’s documented workaround is to run the matching driver at /snap/bin/geckodriver; a shared, accessible profile directory or a non-container browser-and-driver installation are alternatives. Headless mode can help when the server has no display, but does not fix profile isolation. These are common leads, not a diagnosis of every kind of Selenium hang.

First determine where the script hangs

“Hangs” can mean different failures: WebDriver never returns from Firefox startup, the browser opens but navigation stalls, or the script gets stuck while closing the session. The Snap/profile problem is most relevant when the wait occurs during driver creation, before your test or page work begins. A page-load stall or slow shutdown may have a different cause.

Before changing packages or upgrading, record the environment for the account that actually runs the job:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Ubuntu release and whether Firefox came from Snap or another package.
  • Selenium version, Firefox version, geckodriver version, and the executable paths in use.
  • The Unix user running the script, especially if it runs through a service, scheduler, or container.
  • The last visible log message and whether Firefox starts, a profile path appears, or the session reaches Marionette.

Mozilla documents the Snap-related issue for the default Firefox shipped with Ubuntu 22.04 and later, but that does not establish that every installation on those releases is affected. Check the package and paths on the machine rather than inferring them from its Ubuntu version. See Mozilla’s geckodriver usage guidance.

Capture geckodriver logs before guessing

Trace output helps show whether the driver started Firefox, which profile it created, and where the handoff stopped. Mozilla describes trace-level output as vital for understanding geckodriver and Firefox issues; Selenium’s Firefox guide also covers configuring log output and levels.

This Python example writes geckodriver output to a file and enables trace logging. Use the service class from Selenium’s Firefox support:

from selenium import webdriver
from selenium.webdriver.firefox.service import Service

service = Service(
    executable_path="/snap/bin/geckodriver",
    service_args=["--log", "trace"],
    log_output="geckodriver.log",
)
driver = webdriver.Firefox(service=service)
try:
    driver.get("https://example.com")
    print(driver.title)
finally:
    driver.quit()

If you are not using Snap Firefox, replace the driver path with the actual geckodriver executable you intend to run. Preserve the complete log, including the lines before and after the apparent stall. Do not discard it after the first error: a failure to launch, a profile access problem, and a browser that launches but does not complete a session have different next steps. See Mozilla’s trace-log instructions and Selenium’s Firefox documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix the Snap Firefox and geckodriver pairing

If Firefox is Ubuntu’s Snap package, first verify that the script uses the geckodriver at /snap/bin/geckodriver. Mozilla explains that the driver must run in the matching Snap environment because of filesystem separation around the generated profile.

Do not set the Firefox binary to /snap/bin/firefox as a shortcut. Mozilla warns that this launcher produces the error “binary is not a Firefox executable” when used this way. If you must explicitly set a binary, use the actual Firefox executable inside the Snap package as documented by Mozilla, not the launcher path. In most cases, test the matching driver path first and only add a custom binary setting if your setup needs one.

For the account that runs Selenium, verify the driver exists and is executable:

ls -l /snap/bin/geckodriver
/snap/bin/geckodriver --version
command -v firefox
id

These checks confirm the file and the current shell’s executable lookup; they do not prove that a scheduler or service runs as the same user or with the same environment. Check the job configuration as well. If it runs under a different account, make sure that account can execute the driver and access the paths involved.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make the temporary profile accessible to both processes

Unless you provide a custom profile, geckodriver creates a temporary, throwaway Firefox profile. Mozilla documents /tmp as the Unix default and says TMPDIR can override it. With Snap’s filesystem boundary, do not assume that Firefox and geckodriver see the automatically generated profile in the same way.

If the trace log indicates a profile visibility or permission problem, choose a non-hidden directory beneath the home directory of the job’s actual user. Check ownership and read/write access for that user. You can set a temporary root before creating the driver:

import os
from pathlib import Path

profile_root = Path.home() / "selenium-tmp"
profile_root.mkdir(mode=0o700, parents=True, exist_ok=True)
os.environ["TMPDIR"] = str(profile_root)

from selenium import webdriver
from selenium.webdriver.firefox.service import Service

service = Service(
    executable_path="/snap/bin/geckodriver",
    service_args=["--log", "trace"],
    log_output="geckodriver.log",
)
driver = webdriver.Firefox(service=service)

Set TMPDIR before creating the WebDriver session, and test it as the same account as the scheduled job. A directory name alone is not a guarantee of access: the driver and browser both need to use a location that their respective execution contexts can reach. If moving the temporary root does not resolve a logged access error, consider a non-container Firefox and geckodriver pairing instead. Mozilla documents both as workarounds, not as universal fixes.

Firefox profile behavior and temporary directory details are described in Mozilla’s profile documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use headless mode only for the display problem

A server may have no graphical display. In that case, pass Firefox’s -headless argument. This addresses display mode; it does not change which filesystem paths Snap exposes to Firefox and geckodriver.

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service

options = Options()
options.add_argument("-headless")
service = Service(
    executable_path="/snap/bin/geckodriver",
    service_args=["--log", "trace"],
    log_output="geckodriver.log",
)
driver = webdriver.Firefox(service=service, options=options)
try:
    driver.get("https://example.com")
    print(driver.title)
finally:
    driver.quit()

If this still stalls at startup, continue with the profile path and trace log rather than treating headless mode as a profile fix. If startup succeeds but a later page request stalls, investigate that point separately.

Choose a remedy that matches the evidence

Remedy When it fits Check or trade-off
/snap/bin/geckodriver You want to keep Ubuntu’s default Snap Firefox and the log points to startup or profile access. Confirm the script actually launches this driver, in the matching Snap environment. Mozilla.
Accessible temporary profile root The log indicates Firefox and geckodriver cannot access the same profile location. Use a non-hidden home subdirectory accessible to both processes and the service account. Mozilla.
Non-container Firefox and geckodriver You want to avoid the container package filesystem boundary. Maintain a compatible browser-and-driver pairing. Mozilla.
-headless The server has no graphical session. It addresses display mode, not profile visibility. Selenium.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check compatibility and driver management

Selenium’s Firefox guide says Selenium 4 requires Firefox 78 or greater and recommends the latest geckodriver. Treat those as general compatibility guidance, not a guarantee for every combination or a cure for filesystem isolation. Record the installed versions and paths, then update deliberately rather than changing multiple variables before collecting logs.

Selenium Manager is included with Selenium releases from 4.6 and can locate or manage a driver when the bindings are not given one. It can help when driver discovery is the problem. Its documentation does not describe it as a fix for the Snap profile boundary, so explicitly verify the driver execution context and profile access if those are implicated. Selenium Manager also notes that a missing Linux shared library can prevent Firefox from running: if the log names a missing library, investigate that dependency rather than treating it as a profile hang. See Selenium Manager documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot by the point of failure

Firefox never starts or driver creation does not return

  • Likely lead: Snap Firefox is paired with a driver outside its expected execution environment, or the generated profile is inaccessible.
  • Try: Confirm Firefox’s package, run /snap/bin/geckodriver, and inspect trace output for the profile path and launch handoff.

The log names a profile path or permission error

  • Likely lead: The account or one of the processes cannot access the temporary profile directory.
  • Try: Use an accessible non-hidden home subdirectory, set TMPDIR before session creation if appropriate, and verify ownership and read/write permissions as the job user.

The browser starts, but there is no display

  • Likely lead: Firefox needs headless mode on this server.
  • Try: Add -headless; if the session still stalls, follow the trace log rather than assuming the display was the only issue.

The log reports a missing shared library

  • Likely lead: Firefox cannot start because a Linux dependency is unavailable.
  • Try: Investigate the specific library named in the log. Selenium Manager documents this as a possible Linux Firefox launch issue.

Startup succeeds, but navigation or shutdown hangs

  • Likely lead: The Snap startup/profile issue does not by itself explain a stall that occurs after session creation.
  • Try: Mark the exact operation where progress stops, retain the full driver log, and investigate that operation rather than repeatedly changing browser packaging.

Or skip the browser setup

If the job only needs a website image or PDF rather than an interactive Selenium session, ScreenshotNeo can capture a page through one API request. It is not a replacement for browser automation or interaction tests. Its clean-shot process accepts cookie/consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. It also offers an MCP server for AI agents, with tools including take_screenshot, get_page_info, and capture_pdf.

Python example, using the API parameters shown in the ScreenshotNeo documentation:

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)

Equivalent cURL call:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Equivalent Node.js request:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.