From 3f00c75bbdb7a91b66be12491c9bc19989a67306 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:04:04 -0500 Subject: [PATCH] time out model downloads that never respond `download_from_url` had no timeout, so a proxy or server that accepted the connection and never answered hung the download forever, including runtime downloads during startup. Connect and read timeouts now fail it like any other download error. The read timeout applies per socket read, so large models still finish. --- frigate/util/downloader.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frigate/util/downloader.py b/frigate/util/downloader.py index 9a8e46ad9f..1755f421ff 100644 --- a/frigate/util/downloader.py +++ b/frigate/util/downloader.py @@ -14,6 +14,10 @@ from frigate.util.file import FileLock logger = logging.getLogger(__name__) +# (connect, read) seconds. The read timeout bounds each socket read rather than +# the whole download, so large models still finish. +DOWNLOAD_TIMEOUT = (15, 60) + # target path -> first line of the last download error for it; every existing # download function swallows its exceptions, so this is how the downloader # thread learns why a file is still missing @@ -124,7 +128,9 @@ class ModelDownloader: logger.info(f"Downloading model file from: {url}") try: - with requests.get(url, stream=True, allow_redirects=True) as r: + with requests.get( + url, stream=True, allow_redirects=True, timeout=DOWNLOAD_TIMEOUT + ) as r: r.raise_for_status() with open(temporary_filename, "wb") as f: for chunk in r.iter_content(chunk_size=8192):