testcontainers / testcontainers/testcontainers-python
Bug: file descriptor leak in HttpWaitStrategy
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.3k
- Forks
- 386
- Avg merge
- 4h 40m
- Merged PRs (30d)
- 1
Description
Describe the bug
When using an HttpWaitStrategy in DockerContainer.waiting_for and the container image respond with an error code, the underlying HttpError is not correctly handled, leaking a file descriptor.
To Reproduce
Example with the https://hub.docker.com/r/typesense/typesense image, but should work with any image providing a HTTP server that takes a few seconds to start:
# mre.py
from testcontainers.core.container import DockerContainer
from testcontainers.core.wait_strategies import HttpWaitStrategy
print("starting")
with (
DockerContainer("typesense/typesense:30.2", command="--data-dir /home --api-key=whatever --enable-cors")
.with_exposed_ports(8108)
.waiting_for(HttpWaitStrategy(8108, "/health").for_status_code(200))
):
print("ok")
$ python -Werror::ResourceWarning mre.py
starting
Exception ignored while calling deallocator <function _TemporaryFileCloser.__del__ at 0x101984880>:
Traceback (most recent call last):
File "/Users/loic/.local/share/uv/python/cpython-3.14.4-macos-aarch64-none/lib/python3.14/tempfile.py", line 484, in __del__
_warnings.warn(self.warn_message, ResourceWarning)
ResourceWarning: Implicitly cleaning up <HTTPError 503: ''>
ok
Root Cause / fix
HttpError holds a reference to a (temporary) file storing the HTTP response, so it must be handled in a context manager to safely clean the file when the error is discarded.
Fixed MRE:
# mre.py
from contextlib import nullcontext
from typing import Union
from urllib.error import HTTPError, URLError
from testcontainers.core.container import DockerContainer
from testcontainers.core.wait_strategies import HttpWaitStrategy
class _FixedHttpWaitStrategy(HttpWaitStrategy):
def _handle_http_error(self, error: Union[URLError, HTTPError]) -> bool:
with error if isinstance(error, HTTPError) else nullcontext(error):
return super()._handle_http_error(error)
print("starting")
with (
DockerContainer("typesense/typesense:30.2", command="--data-dir /home --api-key=whatever --enable-cors")
.with_exposed_ports(8108)
.waiting_for(_FixedHttpWaitStrategy(8108, "/health").for_status_code(200))
):
print("ok")
Runtime environment
- MacOS 26.6.2
- Python 3.14.4
- testcontainers 4.14.2
I can work on a PR if you'd like!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at src/testcontainers/core/wait_strategies.py around HttpWaitStrategy._handle_http_error, which the issue identifies as the leak location. Run the provided MRE with -Werror::ResourceWarning against the typesense/typesense image to reproduce it. Done means an HTTP error response is safely cleaned up and the MRE completes without the ResourceWarning.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100