Describe the bug
It seems there is a regression after upgrading from 4.14.2 to 4.15
I was able to reproduce locally (podman) and on Kubernetes (via kubedock) and DOCKER_HOST='tcp://localhost:2475'
To Reproduce
def test_containers():
with PostgresContainer(
"<custom_domain>/postgres:16.4"
) as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("select version()"))
(version,) = result.fetchone()
client = TestClient(app)
response = client.get("/api/todos/1")
assert response.status_code == 200
assert response.json() == {"completed": False, "id": 1, "title": "Todo 1"}
response = client.get("/api/todos")
assert response.status_code == 200
FAILED app/test_main.py::test_containers - docker.errors.DockerException: Error while fetching server API version: maximum recursion depth exceeded
Runtime environment
WSL podman but same behavior on kubedock (Docker API for K8S)
# Get the operating system information (on a unix os).
$ uname -a
6.18.33.2-microsoft-standard-WSL2 #1
# Get the python version.
$ python --version
Python 3.14.5
# Get the docker version and other docker information.
$ docker info
version:
APIVersion: 4.9.3
Built: 0
BuiltTime: Thu Jan 1 01:00:00 1970
GitCommit: ""
GoVersion: go1.22.2
Os: linux
OsArch: linux/amd64
Version: 4.9.3
# Get all python packages.
$ pip freeze
annotated-doc==0.0.4
annotated-types==0.7.0
anyio==4.14.1
babel==2.18.0
backrefs==7.0
beautifulsoup4==4.12.3
certifi==2026.6.17
cfgv==3.5.0
charset-normalizer==3.4.9
click==8.4.1
colorama==0.4.6
coverage==7.15.0
dacite==1.9.2
defusedxml==0.7.1
distlib==0.4.3
docker==7.1.0
fastapi==0.139.2
filelock==3.29.7
ghp-import==2.1.0
gitdb==4.0.12
GitPython==3.1.50
greenlet==3.5.3
h11==0.16.0
httpcore==1.0.9
httpie==3.2.4
httpx==0.28.1
identify==2.6.19
idna==3.18
iniconfig==2.3.0
Jinja2==3.1.6
Markdown==3.10.2
markdown-it-py==4.2.0
markdown_graphviz_inline==1.1.3
MarkupSafe==3.0.3
mdurl==0.1.2
mdx-truly-sane-lists==1.3
mergedeep==1.3.4
mkdocs==1.6.1
mkdocs-autorefs==1.4.4
mkdocs-get-deps==0.2.2
mkdocs-git-latest-changes-plugin==0.0.23
mkdocs-github-admonitions-plugin==0.1.1
mkdocs-include-dir-to-nav==1.2.0
mkdocs-inline-svg-plugin==0.1.5
mkdocs-kroki-plugin==1.6.0
mkdocs-material==9.7.6
mkdocs-material-extensions==1.3.1
mkdocs-monorepo-plugin==1.1.2
mkdocs-multirepo-plugin==0.8.3
mkdocs-nav-weight==0.3.0
mkdocs-redirects==1.2.3
mkdocs-same-dir==0.1.5
mkdocs-techdocs-core==1.7.0
mkdocstrings==1.0.4
multidict==6.7.1
mypy_extensions==1.1.0
nodeenv==1.10.0
packaging==26.2
paginate==0.5.7
pathspec==1.1.1
plantuml-markdown==3.11.2
platformdirs==4.10.0
pluggy==1.6.0
pre_commit==4.6.1
properdocs==1.6.7
psycopg2-binary==2.9.12
pydantic==2.13.4
pydantic_core==2.46.4
Pygments==2.20.0
pymdown-extensions==10.21.3
PySocks==1.7.1
pytest==9.1.1
pytest-cov==7.1.0
python-dateutil==2.9.0.post0
python-discovery==1.4.3
python-dotenv==1.2.2
python-slugify==8.0.4
PyYAML==6.0.3
pyyaml_env_tag==1.1
requests==2.31.0
requests-toolbelt==1.0.0
result==0.17.0
rich==15.0.0
setuptools==83.0.0
six==1.17.0
smmap==5.0.3
soupsieve==2.8.4
SQLAlchemy==2.0.51
starlette==1.3.1
testcontainers==4.15.0
text-unidecode==1.3
typing-inspect==0.8.0
typing-inspection==0.4.2
typing_extensions==4.16.0
urllib3==2.7.0
uvicorn==0.51.0
virtualenv==21.6.0
watchdog==6.0.0
wrapt==2.2.2
On 4.14.2 no issue on both environment
On CI I was able to capture this stacktrace
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:501: in _create_instance
[05:43:48.711+02:00] - .start()
[05:43:48.711+02:00] - ^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:247: in start
[05:43:48.711+02:00] - Reaper.get_instance()
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:472: in get_instance
[05:43:48.711+02:00] - Reaper._instance = Reaper._create_instance()
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:501: in _create_instance
[05:43:48.711+02:00] - .start()
[05:43:48.711+02:00] - ^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:247: in start
[05:43:48.711+02:00] - Reaper.get_instance()
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:472: in get_instance
[05:43:48.711+02:00] - Reaper._instance = Reaper._create_instance()
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:501: in _create_instance
[05:43:48.711+02:00] - .start()
[05:43:48.711+02:00] - ^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:247: in start
[05:43:48.711+02:00] - Reaper.get_instance()
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:472: in get_instance
[05:43:48.711+02:00] - Reaper._instance = Reaper._create_instance()
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:501: in _create_instance
[05:43:48.711+02:00] - .start()
[05:43:48.711+02:00] - ^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:247: in start
[05:43:48.711+02:00] - Reaper.get_instance()
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:472: in get_instance
[05:43:48.711+02:00] - Reaper._instance = Reaper._create_instance()
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:501: in _create_instance
[05:43:48.711+02:00] - .start()
[05:43:48.711+02:00] - ^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:247: in start
[05:43:48.711+02:00] - Reaper.get_instance()
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:472: in get_instance
[05:43:48.711+02:00] - Reaper._instance = Reaper._create_instance()
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:501: in _create_instance
[05:43:48.711+02:00] - .start()
[05:43:48.711+02:00] - ^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:247: in start
[05:43:48.711+02:00] - Reaper.get_instance()
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:472: in get_instance
[05:43:48.711+02:00] - Reaper._instance = Reaper._create_instance()
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:495: in _create_instance
[05:43:48.711+02:00] - DockerContainer(c.ryuk_image)
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/container.py:129: in __init__
[05:43:48.711+02:00] - self._docker = DockerClient(**(docker_client_kw or {}))
[05:43:48.711+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.711+02:00] - ../../../.local/lib/python3.14/site-packages/testcontainers/core/docker_client.py:194: in __init__
[05:43:48.712+02:00] - self.client = docker.from_env(**kwargs)
[05:43:48.712+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.712+02:00] - ../../../.local/lib/python3.14/site-packages/docker/client.py:110: in from_env
[05:43:48.712+02:00] - return cls(
[05:43:48.712+02:00] - ../../../.local/lib/python3.14/site-packages/docker/client.py:48: in __init__
[05:43:48.712+02:00] - self.api = APIClient(*args, **kwargs)
[05:43:48.712+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.712+02:00] - ../../../.local/lib/python3.14/site-packages/docker/api/client.py:207: in __init__
[05:43:48.712+02:00] - self._version = self._retrieve_server_version()
[05:43:48.712+02:00] - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[05:43:48.712+02:00] - _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[05:43:48.712+02:00] -
[05:43:48.712+02:00] - self = <docker.api.client.APIClient object at 0x7f97b2161650>
[05:43:48.712+02:00] -
[05:43:48.712+02:00] - def _retrieve_server_version(self):
[05:43:48.712+02:00] - try:
[05:43:48.712+02:00] - return self.version(api_version=False)["ApiVersion"]
[05:43:48.712+02:00] - except KeyError as ke:
[05:43:48.712+02:00] - raise DockerException(
[05:43:48.712+02:00] - 'Invalid response from docker daemon: key "ApiVersion"'
[05:43:48.712+02:00] - ' is missing.'
[05:43:48.712+02:00] - ) from ke
[05:43:48.712+02:00] - except Exception as e:
[05:43:48.712+02:00] - > raise DockerException(
[05:43:48.712+02:00] - f'Error while fetching server API version: {e}'
[05:43:48.712+02:00] - ) from e
[05:43:48.712+02:00] - E docker.errors.DockerException: Error while fetching server API version: maximum recursion depth exceeded
[05:43:48.712+02:00] -
[05:43:48.712+02:00] - ../../../.local/lib/python3.14/site-packages/docker/api/client.py:230: DockerException
Reaper._create_instance() seems to be called forever
Describe the bug
It seems there is a regression after upgrading from
4.14.2to4.15I was able to reproduce locally (podman) and on Kubernetes (via kubedock) and DOCKER_HOST='tcp://localhost:2475'
To Reproduce
Runtime environment
WSL podman but same behavior on kubedock (Docker API for K8S)
On 4.14.2 no issue on both environment
On CI I was able to capture this stacktrace
Reaper._create_instance() seems to be called forever