Describe the bug
Manual/forced/backlog provider searches can hang for minutes at a time — apparently at random, and on whichever provider happens to be affected on a given run — because the Cloudflare-challenge-bypass path in medusa/session/handlers.py makes an HTTP request with no timeout at all, completely outside Medusa's normal timeout=30 session default.
Root cause
- Every provider session is created with
cloudflare=True (medusa/providers/generic_provider.py, self.session = ProviderSession(cloudflare=True)).
MedusaSession.request() (medusa/session/core.py) properly applies timeout=30 to the initial request, but afterwards, if self.cloudflare is set, unconditionally calls handlers.cloudflare(self, response, timeout=timeout, verify=ssl_cert, **kwargs).
- Inside
handlers.cloudflare() (medusa/session/handlers.py), if the response looks like a Cloudflare IUAM ("I'm Under Attack Mode") or CAPTCHA challenge, it calls:
tokens, user_agent = cf.cloudscraper.get_tokens(original_request.url)
— with no kwargs passed at all, even though kwargs (containing timeout) is available in scope right there (it's used a few lines later, at line 61, for the retry request, but not for this call).
cloudscraper's get_tokens() (vendored at ext/cloudscraper/__init__.py) does scraper.get(url, **kwargs) with whatever it was given — here, nothing — so this request/challenge-solve round trip has no timeout ceiling whatsoever, and can block the calling thread indefinitely if the target site is slow, degraded, or serves an unsolvable challenge.
To Reproduce
Hard to force on demand (depends on a provider actually presenting a Cloudflare IUAM/CAPTCHA challenge to the scraping traffic), but reliably reproduced on live traffic:
- Trigger a manual/forced search for any episode with several torrent providers enabled (in my case: Torrenting, LimeTorrents, ThePirateBay, Eztv).
- Watch
application.log — a Picked <release> as the best result. line appears for one provider, then the next provider in the loop logs Performing episode search for <show> and nothing else follows for anywhere from ~2 to ~4 minutes, before the process either times out via some outer mechanism or the user gives up.
- Direct
curl requests to the exact same provider base URLs, made independently at the same time, return in well under a second — ruling out plain network/DNS/provider-down issues.
- A completely clean process restart does not change the behavior — the same class of hang reproduces immediately, on a different provider, on the very next search. This, plus the fact that it's a different provider each time, points at Cloudflare's adaptive bot detection (probabilistic, not a fixed per-provider fault) rather than a stuck thread or lock.
- At shutdown, the log shows
EVENT-QUEUE :: Waiting for the FORCEDSEARCHQUEUE-MANUAL-... thread to exit, confirming the search thread is genuinely blocked in a network call, not idle.
Expected behavior
The Cloudflare challenge-token request should respect the same timeout as every other request Medusa makes (timeout=30 by default), so a slow/unsolvable challenge fails fast with a clear error instead of hanging the search thread indefinitely.
Suggested fix
In medusa/session/handlers.py::cloudflare(), pass the timeout through to get_tokens():
tokens, user_agent = cf.cloudscraper.get_tokens(original_request.url, timeout=kwargs.get('timeout', 30))
(kwargs already contains timeout at that point, since it's forwarded from MedusaSession.request() — it's just not being used until the retry call a few lines further down.)
Medusa (please complete the following information):
- OS: Debian GNU/Linux 12 (bookworm)
- Branch: master
- Commit: 2bc1eb2
- Python version: 3.11.2
- Database version: 44.19
Additional context
Found while investigating a report on this same instance/session (see #12249, #12250, #12252, #12253) of manual searches for a specific episode (Bar Rescue S10E12) repeatedly freezing right after a result was picked. Log excerpt showing the pattern (different provider hangs each attempt, evidencing this isn't a single dead provider):
Details
2026-07-31 02:27:16 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [Torrenting] :: Picked Bar.Rescue.S10E12.1080p.WEBRip.x264-BAE as the best result.
2026-07-31 02:27:16 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [LimeTorrents] :: Performing episode search for Bar Rescue
2026-07-31 02:27:17 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [ThePirateBay] :: Performing episode search for Bar Rescue
2026-07-31 02:27:17 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [Eztv] :: Performing episode search for Bar Rescue
(~3m50s gap, no further log lines, search restarted by user)
2026-07-31 02:31:07 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [Torrenting] :: Picked Bar.Rescue.S10E12.1080p.WEBRip.x264-BAE as the best result.
2026-07-31 02:31:07 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [LimeTorrents] :: Performing episode search for Bar Rescue
2026-07-31 02:31:07 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [ThePirateBay] :: Performing episode search for Bar Rescue
(~4m gap, no further log lines, search restarted by user)
2026-07-31 02:35:10 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [Torrenting] :: Picked Bar.Rescue.S10E12.1080p.WEBRip.x264-BAE as the best result.
2026-07-31 02:35:10 INFO FORCEDSEARCHQUEUE-MANUAL-731 :: [LimeTorrents] :: Performing episode search for Bar Rescue
(~2m gap, no further log lines, search restarted by user)
Describe the bug
Manual/forced/backlog provider searches can hang for minutes at a time — apparently at random, and on whichever provider happens to be affected on a given run — because the Cloudflare-challenge-bypass path in
medusa/session/handlers.pymakes an HTTP request with no timeout at all, completely outside Medusa's normaltimeout=30session default.Root cause
cloudflare=True(medusa/providers/generic_provider.py,self.session = ProviderSession(cloudflare=True)).MedusaSession.request()(medusa/session/core.py) properly appliestimeout=30to the initial request, but afterwards, ifself.cloudflareis set, unconditionally callshandlers.cloudflare(self, response, timeout=timeout, verify=ssl_cert, **kwargs).handlers.cloudflare()(medusa/session/handlers.py), if the response looks like a Cloudflare IUAM ("I'm Under Attack Mode") or CAPTCHA challenge, it calls:kwargs(containingtimeout) is available in scope right there (it's used a few lines later, at line 61, for the retry request, but not for this call).cloudscraper'sget_tokens()(vendored atext/cloudscraper/__init__.py) doesscraper.get(url, **kwargs)with whatever it was given — here, nothing — so this request/challenge-solve round trip has no timeout ceiling whatsoever, and can block the calling thread indefinitely if the target site is slow, degraded, or serves an unsolvable challenge.To Reproduce
Hard to force on demand (depends on a provider actually presenting a Cloudflare IUAM/CAPTCHA challenge to the scraping traffic), but reliably reproduced on live traffic:
application.log— aPicked <release> as the best result.line appears for one provider, then the next provider in the loop logsPerforming episode search for <show>and nothing else follows for anywhere from ~2 to ~4 minutes, before the process either times out via some outer mechanism or the user gives up.curlrequests to the exact same provider base URLs, made independently at the same time, return in well under a second — ruling out plain network/DNS/provider-down issues.EVENT-QUEUE :: Waiting for the FORCEDSEARCHQUEUE-MANUAL-... thread to exit, confirming the search thread is genuinely blocked in a network call, not idle.Expected behavior
The Cloudflare challenge-token request should respect the same timeout as every other request Medusa makes (
timeout=30by default), so a slow/unsolvable challenge fails fast with a clear error instead of hanging the search thread indefinitely.Suggested fix
In
medusa/session/handlers.py::cloudflare(), pass the timeout through toget_tokens():(
kwargsalready containstimeoutat that point, since it's forwarded fromMedusaSession.request()— it's just not being used until the retry call a few lines further down.)Medusa (please complete the following information):
Additional context
Found while investigating a report on this same instance/session (see #12249, #12250, #12252, #12253) of manual searches for a specific episode (Bar Rescue S10E12) repeatedly freezing right after a result was picked. Log excerpt showing the pattern (different provider hangs each attempt, evidencing this isn't a single dead provider):
Details