Skip to content

Manual/forced search can hang indefinitely: Cloudflare challenge token fetch has no timeout #12254

Description

@DavidHunterJS

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

  1. Every provider session is created with cloudflare=True (medusa/providers/generic_provider.py, self.session = ProviderSession(cloudflare=True)).
  2. 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).
  3. 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).
  4. 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:

  1. Trigger a manual/forced search for any episode with several torrent providers enabled (in my case: Torrenting, LimeTorrents, ThePirateBay, Eztv).
  2. 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.
  3. 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.
  4. 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.
  5. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions