Skip to content

[🐛 Bug]: selenium/standalone-chrome:4.31.0 container fails to save downloaded files (works on 4.30.0) #2804

@Elmo33

Description

@Elmo33

Description

Description:

(skip to the comment I made for a quick sum up of the issue)

  • What you were trying to do:
    I was running automated Selenium tests in Docker using the selenium/standalone-chrome:4.31.0 image to download and verify a PDF file during automated test runs in GitHub Actions CI.

  • What you expected to happen:
    The file should download successfully to the mounted volume (/opt/selenium/assets within the container, /tmp/target on the host) and be available after the download completes.

  • What actually happened:
    The browser visually indicates the file download completes successfully. However, instead of the PDF, a folder with a random Selenium session ID appears on disk with no PDF file inside. This issue specifically occurs when running tests on GitHub Actions using the 4.31.0 Selenium Docker image. Downgrading to 4.30.0 resolves the issue completely, and the file correctly appears as expected.

Additional relevant context:

  • The issue does not occur on my local setup (Ubuntu 22.04) but consistently happens on GitHub Actions CI (Ubuntu 24.04).
  • Issue explicitly appeared after upgrading from Selenium Docker image 4.30.0 to 4.31.0. I also noticed exact same issue on version 4.18.1-20240224
  • local docker compose v2.32.4, github docker compose v2.29.6
  • Docker Compose configuration snippet:
  selenium-standalone:
    image: selenium/standalone-chrome:4.31.0
    container_name: selenium-docker
    ports:
      - "4444:4444"
    volumes:
      - /dev/shm:/dev/shm
      - /tmp/target:/opt/selenium/assets
#      - ./config.toml:/opt/bin/config.toml
      - /var/run/docker.sock:/var/run/docker.sock
    privileged: true
    networks:
      - selenium-grid

Reproducible Code

**Reproducible Code:**


from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time, glob, os

options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--headless=new")

prefs = {
    "download.default_directory": "/opt/selenium/assets",
    "download.prompt_for_download": False,
    "download.directory_upgrade": True,
}
options.add_experimental_option("prefs", prefs)

driver = webdriver.Remote(command_executor="http://localhost:4444", options=options)

# Navigate to a page and trigger PDF download
driver.get("<URL_THAT_TRIGGERS_PDF_DOWNLOAD>")  
driver.find_element(By.CSS_SELECTOR, "<PDF_DOWNLOAD_BUTTON>").click()
time.sleep(10)  # Wait to ensure download completes

driver.quit()

# Verify PDF download
pdf_files = glob.glob("/tmp/target/*.pdf")
assert pdf_files, f"PDF was not downloaded. Directory contents: {os.listdir('/tmp/target')}"


*Note:* Replace placeholders (`<URL_THAT_TRIGGERS_PDF_DOWNLOAD>` and `<PDF_DOWNLOAD_BUTTON>`) with your specific URL and CSS selector.
Also this is just a simulation of the scenario that i am executing.

Debugging Logs

**Debugging Logs and Environment Details:**

**Operating System and Environment (GitHub Runner):**

Linux github-hetzner-runner 6.8.0-52-generic SeleniumHQ/selenium#53-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
Ubuntu 24.04.1 LTS (Noble Numbat)


**Docker and Docker Compose Versions:**

Docker version 27.5.1, build 9f9e405
Docker Compose version v2.29.6


**Python and Selenium Client Versions:**

Python 3.12.3
selenium==4.28.1 (client library)


**Chrome and Chromedriver (within Selenium container 4.31.0):**
- Google Chrome: Version 124.x (exact version from docker container)
- Chromedriver: Version 124.x (exact version from docker container)

*Note:*  
Due to Docker image startup error during details collection (`Error: Process completed with exit code 1`), specific Chrome/Chromedriver versions inside `4.31.0` are assumed as standard matching bundled versions (124.x), based on Selenium image standard practice.

**File system checks (after test completion):**
- Expected mount point `/tmp/target` shows a directory named with session ID but no `.pdf` files.
- The file appears downloaded within the browser (Selenium video logs confirm visual download completion), but not physically present on disk.

ℹ️ Last known working version: 4.30.0

Activity

selenium-ci

selenium-ci commented on Apr 22, 2025

@selenium-ci
Member

@Elmo33, thank you for creating this issue. We will troubleshoot it as soon as we can.

Selenium Triage Team: remember to follow the Triage Guide

Elmo33

Elmo33 commented on Apr 22, 2025

@Elmo33
Author

I think I found the real issue, which is summed up here:
1.Selenium image:
selenium/standalone-docker:4.31.0
docker compose version:
v2.29.6
-FAIL-

2.Selenium image:
selenium/standalone-chrome:4.31.0
docker compose version:
v2.29.6
-PASS-

3.Selenium image:
selenium/standalone-docker:4.31.0
docker compose version:
v2.32.4
-PASS-

Which proves that my issue was caused by the specific combination of the docker compose image and current standalone-docker image (the fact that chrome image directly works with the old version is weird).

titusfortner

titusfortner commented on Apr 22, 2025

@titusfortner
Member

Have you tried using the download mechanism built into selenium grid?

https://www.selenium.dev/documentation/webdriver/drivers/remote_webdriver/#downloads

Elmo33

Elmo33 commented on Apr 23, 2025

@Elmo33
Author

I tried adding this :

remote_chrome_options.set_capability("se:downloadsEnabled", True)

which resulted in docker container not starting ( timing out ), i am assuming I am doing it wrong?

After little bit of tinkering ( changing versions and options ) and restoring the code back to the working version, now I get this error.

Image

Which is really weird, since I haven't changed anything in my code while it was working 1 hour ago before I did this "tinkering", (I can 100% say code is same with version control)

I minimized my remote chrome settings to make it more readable and it basically looks like this:

def create_remote_driver(hub_url):
    chrome_options = Options()
    chrome_options.add_argument("--disable-infobars")
    chrome_options.add_argument("--incognito")
    chrome_options.add_experimental_option("prefs", {
        "download.prompt_for_download": False,
        "download.directory_upgrade": True,
        "download.default_directory": "/opt/selenium/assets",
    })
    chrome_options.set_capability("browserName", "chrome")
    chrome_options.set_capability("se:downloadsEnabled", True)
    chrome_options.set_capability("se:screenResolution", "1920x1080")
    chrome_options.set_capability("goog:loggingPrefs", {
        "browser": "ALL",
        "performance": "ALL"
    })

    driver = Remote(command_executor=hub_url, options=chrome_options)

    driver.execute_cdp_cmd("Page.setDownloadBehavior", {
        "behavior": "allow",
        "downloadPath": "/opt/selenium/assets"
    })

    return driver

note that I had to add

    driver.execute_cdp_cmd("Page.setDownloadBehavior", {
        "behavior": "allow",
        "downloadPath": "/opt/selenium/assets"
    })

because otherwise the download window would keep opening the download window which would fail the test.

Also I tried adding the enable managed downloads flag with

chrome_options.add_argument("--enable-managed-downloads true")

which didnt have any effect.

Elmo33

Elmo33 commented on Apr 23, 2025

@Elmo33
Author

another observation, idk if it matters:
if I remove

            driver.execute_cdp_cmd(
                "Page.setDownloadBehavior",
                {
                    "behavior": "allow",
                    "downloadPath": download_path,
                },
            )

and manually click the save button in the download window (while logged into the grid session) , it is able to download the file (without permission issues).

If i reenable it, then its same.

titusfortner

titusfortner commented on Apr 23, 2025

@titusfortner
Member

i am assuming I am doing it wrong?

You also have to start the server with: --enable-managed-downloads true
If you do this, Selenium will create a unique download directory for the session, so you wouldn't want to override default_directory yourself. Perhaps the download directory is attempting to get set in 2 different places in your code?

Elmo33

Elmo33 commented on Apr 24, 2025

@Elmo33
Author

how do i use that flag with the server in the docker file? whatever i tried didnt work.

titusfortner

titusfortner commented on Apr 24, 2025

@titusfortner
Member

@VietND96 i don't know how our docker settings work. At first glance it seems like enabling downloads is the default behavior, resulting in this confusion. Can you clarify?

VietND96

VietND96 commented on Apr 24, 2025

@VietND96
Member

Looks like you are using local download, and via docker volume to mount the download dir in the container to the host and verify the file exist.

selenium/standalone-docker:4.31.0
docker compose version:
v2.29.6
-FAIL-

This image is different with others (standalone chrome/edge/firefox), it is Dynamic Grid, which is spin up Node dynamically based on coming request, and it requires Docker Daemonset to send Docker API.
May I know the full compose file for this image?

Elmo33

Elmo33 commented on Apr 24, 2025

@Elmo33
Author
# To execute this docker-compose yml file use `docker-compose -f docker-compose.yml up`
# Add the `-d` flag at the end for detached execution
# To stop the execution, hit Ctrl+C, and then `docker-compose -f docker-compose.yml down`

services:
  selenium-standalone:
    image: selenium/standalone-docker:4.31.0
    container_name: selenium-docker
    ports:
      - "4444:4444"
    volumes:
      - /dev/shm:/dev/shm
      - /tmp/target:/opt/selenium/assets
      - /var/run/docker.sock:/var/run/docker.sock
    privileged: true
    networks:
      - selenium-grid

  clickhouse-client:
    image: clickhouse/clickhouse-server:23.8.3.48-alpine
    container_name: clickhouse-client
    stdin_open: true
    tty: true
    entrypoint: [ "bash" ]
    networks:
      - selenium-grid

networks:
  selenium-grid:
    driver: bridge

VietND96

VietND96 commented on Apr 24, 2025

@VietND96
Member

With this compose file, dynamic using the default TOML config could be seen here https://github.com/SeleniumHQ/docker-selenium/blob/trunk/NodeDocker/config.toml
In this default config has

host-config-keys = ["Dns", "DnsOptions", "DnsSearch", "ExtraHosts", "Binds"]

which was just added in latest image tag, that is used to share all host config (include volume mount) from standalone-docker to browser containers spin up. It means the volume config /tmp/target:/opt/selenium/assets also present in standalone-chrome container spin up when a Chrome request comes (you can inspect it by executing docker ps in host when a session is on going).

And probably docker compose version v2.29.6 not working properly when having this config added (I also checked, this version was released in 2019). In my local is using version v2.34.0 could not reproduce the issue.
I don't know what is the minimum version of docker compose could work with this new config, need to do the evaluation. However, without software version upgrade restriction, I think it is good if we start using recent version of docker compose.

Elmo33

Elmo33 commented on Apr 24, 2025

@Elmo33
Author

@VietND96 Makes sense, the main problem was the lack of any kind of logs or hints what was the problem. I was updating versions of my project's dependancies and unfortunately I chose selenium image to be first, then it took me 4 hours to realize it was the relation of selenium version with docker version.

I believe many other people could potentially come across this problem ( while having outdated docker compose for some reasons and new selenium version ), which is the main reason I reported it and didn't just proceed with updating my libraries and ignoring it.

VietND96

VietND96 commented on Apr 24, 2025

@VietND96
Member

I moved this issue to repo docker-selenium. I will update the README with something like system requirements to mention the recommended versions of Docker engine and Docker Compose to use.

github-actions

github-actions commented on Aug 1, 2025

@github-actions

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

locked and limited conversation to collaborators on Aug 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @titusfortner@selenium-ci@VietND96@Elmo33

      Issue actions

        [🐛 Bug]: selenium/standalone-chrome:4.31.0 container fails to save downloaded files (works on 4.30.0) · Issue #2804 · SeleniumHQ/docker-selenium