netdata/netdata · error · ReadTimeoutError
Read timed out. (read timeout=%s)
Error message
Read timed out. (read timeout=%s)
What it means
Raised from ConnectionPool._raise_timeout (first branch) when the exception caught during _make_request is a socket.timeout raised by a blocking read/recv on the established connection. The TCP connection succeeded, but the server did not send a complete response within the read timeout. This is the classic server-side slowness timeout, distinct from a connect timeout.
Source
Thrown at src/collectors/python.d.plugin/python_modules/urllib3/connectionpool.py:309
pass
def _get_timeout(self, timeout):
""" Helper that always returns a :class:`urllib3.util.Timeout` """
if timeout is _Default:
return self.timeout.clone()
if isinstance(timeout, Timeout):
return timeout.clone()
else:
# User passed us an int/float. This is for backwards compatibility,
# can be removed later
return Timeout.from_float(timeout)
def _raise_timeout(self, err, url, timeout_value):
"""Is the error actually a timeout? Will raise a ReadTimeout or pass"""
if isinstance(err, SocketTimeout):
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
# See the above comment about EAGAIN in Python 3. In Python 2 we have
# to specifically catch it and throw the timeout error
if hasattr(err, 'errno') and err.errno in _blocking_errnos:
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
# Catch possible read timeouts thrown as SSL errors. If not the
# case, rethrow the original. We need to do this because of:
# http://bugs.python.org/issue10272
if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
def _make_request(self, conn, method, url, timeout=_Default, chunked=False,
**httplib_request_kw):
"""
Perform a request on a given urllib connection object taken from our
pool.
View on GitHub (pinned to 4864de85e2)
Solutions
- Increase the read timeout: timeout=urllib3.Timeout(connect=5, read=60), sized to the endpoint's slowest legitimate response.
- Reproduce with curl -w '%{time_total}' to measure how long the endpoint actually takes; if it exceeds your timeout, fix the server or the timeout.
- If it happens on reused connections after idle periods, disable keep-alive or set retries=Retry(read=1) and a smaller pool maxsize so stale connections are replaced (urllib3 re-tries idempotent requests).
- Check server health (CPU, DB locks, GC pauses) when the timeout is intermittent.
- For large downloads, stream with preload_content=False and read in chunks so no single recv blocks past the window.
Example fix
# before
r = pool.urlopen('GET', '/slow-report', timeout=5)
# after
r = pool.urlopen('GET', '/slow-report', timeout=urllib3.Timeout(connect=5, read=120), retries=urllib3.util.retry.Retry(read=2)) Defensive patterns
Strategy: retry
Try / catch
from urllib3.exceptions import ReadTimeoutError, MaxRetryError
try:
r = pool.urlopen('GET', url, timeout=urllib3.Timeout(connect=5, read=60))
except (ReadTimeoutError, MaxRetryError) as e:
if 'Read timed out' in str(e):
logger.warning('slow response from %s - consider raising read timeout', url)
raise Prevention
- Measure the endpoint's p99 response time and set read timeout above it (e.g. 2-3x).
- Use Retry(read=2, backoff_factor=0.5) for idempotent GETs so one slow response is retried.
- For big payloads, stream responses (preload_content=False) so no single recv waits for the whole body.
- Keep-alive idle gaps shorter than any intermediary LB idle timeout to avoid semi-closed sockets.
When it happens
Trigger: GET/POST via HTTPConnectionPool.urlopen where the server accepts the request, then stalls: slow backend script, lock contention, giant response streamed slower than the read timeout, or an idle keep-alive connection that the server closed without FIN being seen. timeout_value is the read timeout in effect (from Timeout.read or the float form).
Common situations: Default read timeout too small for a slow endpoint (report generation, heavy DB queries); keep-alive reuse of a connection that a load balancer silently dropped (idle timeout < LB keepalive); monitoring agents polling a slow status page; reverse proxy buffering a slow upstream.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Connection to %s timed out. (connect timeout=%s)
- Connection to %s timed out. (connect timeout=%s)
- Read timed out.
- Failed to establish a new connection: %s
- Failed to establish a new connection: %s
AI-assisted analysis of netdata/netdata@4864de85e2 (2026-08-15).
Data as JSON: /api/errors/08e1c4b9e18146d0.
Report an issue: GitHub.