Passing timeouts as a string fails with FullPoolError(HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.))
# Reproducing steps
Considering this code, where timeout is a string, which is incorrect:
```python
from elasticsearch import Elasticsearch
client = Elasticsearch("http://localhost:9200", basic_auth=("elastic", "changeme"), request_timeout="1")
client.info()
```
# What happens
The code fails as follows:
```python
perform_request GET / None {'user-agent': 'elasticsearch-py/9.4.0 (Python/3.14.0; elastic-transport/9.4.0)', 'connection': 'keep-alive', 'authorization': 'Basic <hidden>', 'accept': 'application/vnd.elasticsearch+json; compatible-with=9', 'x-elastic-client-meta': 'es=9.4.0,py=3.14.0,t=9.4.0,ur=2.6.3'} {'timeout': '1'}
HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.
perform_request GET / None {'user-agent': 'elasticsearch-py/9.4.0 (Python/3.14.0; elastic-transport/9.4.0)', 'connection': 'keep-alive', 'authorization': 'Basic <hidden>', 'accept': 'application/vnd.elasticsearch+json; compatible-with=9', 'x-elastic-client-meta': 'es=9.4.0,py=3.14.0,t=9.4.0,ur=2.6.3'} {'timeout': '1'}
HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.
perform_request GET / None {'user-agent': 'elasticsearch-py/9.4.0 (Python/3.14.0; elastic-transport/9.4.0)', 'connection': 'keep-alive', 'authorization': 'Basic <hidden>', 'accept': 'application/vnd.elasticsearch+json; compatible-with=9', 'x-elastic-client-meta': 'es=9.4.0,py=3.14.0,t=9.4.0,ur=2.6.3'} {'timeout': '1'}
HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.
perform_request GET / None {'user-agent': 'elasticsearch-py/9.4.0 (Python/3.14.0; elastic-transport/9.4.0)', 'connection': 'keep-alive', 'authorization': 'Basic <hidden>', 'accept': 'application/vnd.elasticsearch+json; compatible-with=9', 'x-elastic-client-meta': 'es=9.4.0,py=3.14.0,t=9.4.0,ur=2.6.3'} {'timeout': '1'}
HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.
Traceback (most recent call last):
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/elastic_transport/_node/_http_urllib3.py", line 168, in perform_request
response = self.pool.urlopen(
method,
...<4 lines>...
**kw, # type: ignore[arg-type]
)
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/connectionpool.py", line 864, in urlopen
self._put_conn(conn)
~~~~~~~~~~~~~~^^^^^^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/connectionpool.py", line 322, in _put_conn
raise FullPoolError(
...<2 lines>...
) from None
urllib3.exceptions.FullPoolError: HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".../elasticsearch-py/t.py", line 4, in <module>
client.info()
~~~~~~~~~~~^^
File ".../elasticsearch-py/elasticsearch/_sync/client/utils.py", line 421, in wrapped
return api(*args, **kwargs)
File ".../elasticsearch-py/elasticsearch/_sync/client/__init__.py", line 3028, in info
return self.perform_request( # type: ignore[return-value]
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"GET",
^^^^^^
...<4 lines>...
path_parts=__path_parts,
^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File ".../elasticsearch-py/elasticsearch/_sync/client/_base.py", line 272, in perform_request
response = self._perform_request(
method,
...<4 lines>...
otel_span=otel_span,
)
File ".../elasticsearch-py/elasticsearch/_sync/client/_base.py", line 320, in _perform_request
meta, resp_body = self.transport.perform_request(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
method,
^^^^^^^
...<8 lines>...
otel_span=otel_span,
^^^^^^^^^^^^^^^^^^^^
)
^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/elastic_transport/_transport.py", line 346, in perform_request
resp = node.perform_request(
method,
...<3 lines>...
request_timeout=request_timeout,
)
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/elastic_transport/_node/_http_urllib3.py", line 204, in perform_request
raise err from e
elastic_transport.ConnectionError: Connection error caused by: ConnectionError(Connection error caused by: FullPoolError(HTTPConnectionPool(host='localhost', port=9200): Pool reached maximum size and no more connections are allowed.))
```
The error has nothing to do with the root cause.
# What you expected to happen
I expected a clear error, like what happens with this urllib3-native code:
```python
import urllib3
r = urllib3.request(
"GET",
"http://localhost:9200/",
headers=urllib3.make_headers(basic_auth="elastic:changeme"),
timeout="1",
)
print(r.json())
```
which fails with a clear error:
```python
Traceback (most recent call last):
File ".../elasticsearch-py/t2.py", line 3, in <module>
r = urllib3.request(
"GET",
...<2 lines>...
timeout="1",
)
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/__init__.py", line 193, in request
return _DEFAULT_POOL.request(
~~~~~~~~~~~~~~~~~~~~~^
method,
^^^^^^^
...<9 lines>...
json=json,
^^^^^^^^^^
)
^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/_request_methods.py", line 135, in request
return self.request_encode_url(
~~~~~~~~~~~~~~~~~~~~~~~^
method,
^^^^^^^
...<3 lines>...
**urlopen_kw,
^^^^^^^^^^^^^
)
^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/_request_methods.py", line 182, in request_encode_url
return self.urlopen(method, url, **extra_kw)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/poolmanager.py", line 457, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/connectionpool.py", line 765, in urlopen
timeout_obj = self._get_timeout(timeout)
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/connectionpool.py", line 356, in _get_timeout
return Timeout.from_float(timeout)
~~~~~~~~~~~~~~~~~~^^^^^^^^^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/util/timeout.py", line 186, in from_float
return Timeout(read=timeout, connect=timeout)
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/util/timeout.py", line 115, in __init__
self._connect = self._validate_timeout(connect, "connect")
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File ".../elasticsearch-py/.venv/lib/python3.14t/site-packages/urllib3/util/timeout.py", line 165, in _validate_timeout
raise ValueError(
...<2 lines>...
) from None
ValueError: Timeout value connect was 1, but it must be an int, float or None.
```
I tried reproducing from elastic-transport, but failed to do so, sorry.
关闭于 2026-05-26 3 条评论