You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: website_and_docs/content/blog/2026/selenium-grid-4-41-deep-dive.md
+13-16Lines changed: 13 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,16 +11,13 @@ description: >
11
11
We are excited to ship Selenium Grid 4.41.0 — and this release brings something meaningful for you
12
12
---
13
13
14
-
# Selenium Grid 4.41.0: What's New and Why It Matters
15
-
16
-
---
14
+
We are excited to ship Selenium Grid **4.41.0** 🎉 — and this might be one of impactful releases in recent memory. Whether you are running Grid in a bare-metal lab, a Docker Compose stack, or a sprawling Kubernetes cluster, this release brings something meaningful for you. From a brand-new **Dynamic Grid for Kubernetes**, a powerful **Session Event API**, to smarter video recording and a rock-solid Distributor, let's dig in.
17
15
18
-
## Overview
19
-
20
-
We are excited to ship Selenium Grid **4.41.0** — and this might be one of impactful releases in recent memory. Whether you are running Grid in a bare-metal lab, a Docker Compose stack, or a sprawling Kubernetes cluster, this release brings something meaningful for you. From a brand-new **Dynamic Grid for Kubernetes**, a powerful **Session Event API**, to smarter video recording and a rock-solid Distributor, let's dig in.
21
16
22
17
---
23
18
19
+
# Selenium Grid 4.41.0: What's New and Why It Matters
20
+
24
21
## 1. Dynamic Grid, Now Native on Kubernetes
25
22
26
23
The headline feature of 4.41.0 is unambiguous: **Dynamic Grid now runs natively inside Kubernetes clusters** ([selenium#17092](https://github.com/SeleniumHQ/selenium/pull/17092), [docker-selenium#3082](https://github.com/SeleniumHQ/docker-selenium/pull/3082)).
@@ -408,23 +405,23 @@ A new [`traefik-servers-transport.yaml`](https://github.com/SeleniumHQ/docker-se
408
405
409
406
Three significant Distributor fixes ship in 4.41.0, addressing real concurrency issues that could manifest under load.
**Fix 1: Thread exhaustion in health-check cycle ([selenium#17104](https://github.com/SeleniumHQ/selenium/pull/17104), commit [`d8195c8`](https://github.com/SeleniumHQ/selenium/commit/d8195c8aa617c54d191523a5210f972978965b93))**
412
409
413
410
The `LocalDistributor` runs periodic health checks against all registered nodes. Under high node counts, a subtle bug caused the health-check executor thread pool to accumulate tasks faster than they were being consumed, eventually exhausting threads and causing new session requests to stall.
414
411
415
412
The fix refactors [`LocalNodeRegistry.java`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/src/org/openqa/selenium/grid/distributor/local/LocalNodeRegistry.java) to decouple the health-check scheduling from the main distribution path, with 295 lines of new tests specifically exercising concurrent health-check scenarios.
[`ProxyNodeWebsockets`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/src/org/openqa/selenium/grid/node/ProxyNodeWebsockets.java) tracks active WebSocket connections per node to respect `maxSessions`. A race condition in the connection bookkeeping could cause the counter to drift upward, making slots appear occupied when they were free. Over time this would cause nodes to appear artificially full.
420
417
421
418
The fix tightens the lifecycle management with try-finally guards around counter decrements, backed by 406 lines of dedicated unit tests.
**Fix 3: Retry session on executor shutdown ([selenium#17109](https://github.com/SeleniumHQ/selenium/pull/17109), commit [`527a40b`](https://github.com/SeleniumHQ/selenium/commit/527a40b30f01b272c1b7df1de122f8b16e3f79ce))**
424
421
425
422
When a [`RemoteNode`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/src/org/openqa/selenium/grid/node/remote/RemoteNode.java)'s thread executor enters a shutdown state (e.g., during a graceful drain), session creation requests could be silently dropped instead of being returned to the queue for redistribution. The Distributor now detects `RejectedExecutionException` from a shutting-down executor and transparently retries the session on another available node.
[`LocalGridModel`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/src/org/openqa/selenium/grid/distributor/local/LocalGridModel.java) contained a lock inversion risk between its internal state lock and the event bus listener lock. Under specific timing conditions this could deadlock the Distributor entirely. The fix restructures lock acquisition order with a dedicated test ([`LocalGridModelDeadlockTest.java`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/test/org/openqa/selenium/grid/distributor/local/LocalGridModelDeadlockTest.java), 275 lines) that explicitly reproduces the hazard.
430
427
@@ -463,19 +460,19 @@ Complementing the above, the Fluxbox desktop inside every node and standalone im
Configuration environment variables are now shared across [`NodeDocker`](https://github.com/SeleniumHQ/docker-selenium/tree/4.41.0-20260222/NodeDocker), [`StandaloneDocker`](https://github.com/SeleniumHQ/docker-selenium/tree/4.41.0-20260222/StandaloneDocker), [`NodeKubernetes`](https://github.com/SeleniumHQ/docker-selenium/tree/4.41.0-20260222/NodeKubernetes), and [`StandaloneKubernetes`](https://github.com/SeleniumHQ/docker-selenium/tree/4.41.0-20260222/StandaloneKubernetes) images. Variables like `SE_NODE_GRID_URL`, `SE_NODE_MAX_SESSIONS`, and video-related settings behave identically regardless of whether the Dynamic Grid backend is Docker or Kubernetes.
469
466
470
-
### Basic auth support in Dynamic Grid Standalone ([selenium#17072](https://github.com/SeleniumHQ/selenium/pull/17072), commit [`7278252`](https://github.com/SeleniumHQ/selenium/commit/7278252badc14d9d036df8ca20d6927b5f546a49))
467
+
**Basic auth support in Dynamic Grid Standalone ([selenium#17072](https://github.com/SeleniumHQ/selenium/pull/17072), commit [`7278252`](https://github.com/SeleniumHQ/selenium/commit/7278252badc14d9d036df8ca20d6927b5f546a49))**
471
468
472
469
When Grid Standalone is secured with HTTP basic auth, [`DockerSessionFactory`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java) now correctly forwards credentials when communicating with the node's own status endpoint during session setup. A small but important fix that unblocks secured Dynamic Grid deployments.
473
470
474
-
### Restore stereotype capability merging in RelaySessionFactory ([selenium#17097](https://github.com/SeleniumHQ/selenium/pull/17097), commit [`ac74b7e`](https://github.com/SeleniumHQ/selenium/commit/ac74b7e263e1308c3f5f8c666c8c2cb97da3e417))
471
+
**Restore stereotype capability merging in RelaySessionFactory ([selenium#17097](https://github.com/SeleniumHQ/selenium/pull/17097), commit [`ac74b7e`](https://github.com/SeleniumHQ/selenium/commit/ac74b7e263e1308c3f5f8c666c8c2cb97da3e417))**
475
472
476
473
A regression introduced in a prior release caused [`RelaySessionFactory`](https://github.com/SeleniumHQ/selenium/blob/selenium-4.41.0/java/src/org/openqa/selenium/grid/node/relay/RelaySessionFactory.java) to ignore stereotype capabilities during session creation, which broke mobile relay sessions that relied on custom capabilities from the stereotype being merged into the session request. Restored and covered by 156 lines of new tests.
477
474
478
-
### Kubernetes: structured logs support ([docker-selenium#3087](https://github.com/SeleniumHQ/docker-selenium/pull/3087), commit [`ccd697c`](https://github.com/SeleniumHQ/docker-selenium/commit/ccd697cef2b13904c628b5d968447df1e7c30ed4))
475
+
**Kubernetes: structured logs support ([docker-selenium#3087](https://github.com/SeleniumHQ/docker-selenium/pull/3087), commit [`ccd697c`](https://github.com/SeleniumHQ/docker-selenium/commit/ccd697cef2b13904c628b5d968447df1e7c30ed4))**
479
476
480
477
Structured logging (`global.seleniumGrid.structuredLogs`) already existed, but plain-text logs were always emitted alongside it with no way to suppress them. This PR adds `SE_PLAIN_LOGS` (`--plain-logs`, default `true`) as an independent toggle. Both modes can run simultaneously — to get pure JSON output for a log aggregation pipeline (Loki, Elasticsearch), enable structured logs and turn plain logs off:
481
478
@@ -493,7 +490,7 @@ Or via environment variable on any component directly:
493
490
SE_PLAIN_LOGS=false
494
491
```
495
492
496
-
### Kubernetes: tolerations fix for monitoring exporter ([docker-selenium#3086](https://github.com/SeleniumHQ/docker-selenium/pull/3086), commit [`56e0192`](https://github.com/SeleniumHQ/docker-selenium/commit/56e0192c))
493
+
**Kubernetes: tolerations fix for monitoring exporter ([docker-selenium#3086](https://github.com/SeleniumHQ/docker-selenium/pull/3086), commit [`56e0192`](https://github.com/SeleniumHQ/docker-selenium/commit/56e0192c))**
497
494
498
495
The Helm chart's monitoring exporter deployment was missing `tolerations`, which caused it to fail scheduling on tainted nodes (a common pattern in production clusters with dedicated node pools). This is now fixed.
499
496
@@ -507,7 +504,7 @@ The Helm chart's monitoring exporter deployment was missing `tolerations`, which
0 commit comments