ytdl-org/youtube-dl · warning · ExtractorError
Found multiple matching extractors: %s
Error message
Found multiple matching extractors: %s
What it means
Raised by the testurl extractor when the user-supplied case-insensitive regex matches MORE THAN one extractor IE_NAME and none of them matches the pattern exactly (case-insensitive equality). The names of all matches are listed in the error. Marked expected=True.
Source
Thrown at youtube_dl/extractor/testurl.py:38
extractor_id = mobj.group('extractor')
all_extractors = gen_extractors()
rex = re.compile(extractor_id, flags=re.IGNORECASE)
matching_extractors = [
e for e in all_extractors if rex.search(e.IE_NAME)]
if len(matching_extractors) == 0:
raise ExtractorError(
'No extractors matching %r found' % extractor_id,
expected=True)
elif len(matching_extractors) > 1:
# Is it obvious which one to pick?
try:
extractor = next(
ie for ie in matching_extractors
if ie.IE_NAME.lower() == extractor_id.lower())
except StopIteration:
raise ExtractorError(
('Found multiple matching extractors: %s' %
' '.join(ie.IE_NAME for ie in matching_extractors)),
expected=True)
else:
extractor = matching_extractors[0]
num_str = mobj.group('num')
num = int(num_str) if num_str else 0
testcases = []
t = getattr(extractor, '_TEST', None)
if t:
testcases.append(t)
testcases.extend(getattr(extractor, '_TESTS', []))
try:
tc = testcases[num]
except IndexError:View on GitHub (pinned to 956b8c5855)
Solutions
- Use the exact extractor name: youtube-dl --list-extractors, then pass that name verbatim, e.g. testurl:ExactName (exact case-insensitive match disambiguates automatically).
- Anchor the regex if you intended one extractor: testurl:^vimeo$.
- Read the listed candidate names in the error message and pick one.
Example fix
# before (ambiguous, matches many) # youtube-dl testurl:tube # after (exact single match) # youtube-dl --list-extractors | grep -ix 'vimeo' # youtube-dl testurl:vimeo
Defensive patterns
Strategy: validation
Validate before calling
import subprocess, re
names = subprocess.run(['youtube-dl', '--list-extractors'], capture_output=True, text=True).stdout.splitlines()
hits = [n for n in names if re.search(pattern, n, re.IGNORECASE)]
if len(hits) > 1 and not any(n.lower() == pattern.lower() for n in hits):
print('ambiguous pattern; candidates:', hits) Type guard
def unambiguous(pattern, names):
"""Return the single extractor for a testurl pattern, else None."""
hits = [n for n in names if re.search(pattern, n, re.IGNORECASE)]
if len(hits) == 1:
return hits[0]
exact = [n for n in hits if n.lower() == pattern.lower()]
return exact[0] if len(exact) == 1 else None Try / catch
try:
ydl.extract_info('testurl:%s' % pattern)
except ExtractorError as e:
if e.expected and 'multiple matching extractors' in str(e):
pick_exact_name_from(e) # candidates are listed in the message
raise Prevention
- Use exact extractor names or anchored regexes (^name$) for testurl.
- Check candidate lists in the error message before retrying.
- Avoid substrings like 'tube'/'music' that hit many IE_NAMEs.
When it happens
Trigger: A testurl:<pattern> URL where the pattern is a substring of several extractor names (e.g. 'tube' matching many '*tube*' IEs) and is not exactly equal to any single IE_NAME.
Common situations: Overly broad patterns like testurl:tube or testurl:music; users unaware the pattern is a regex matched against every IE_NAME.
Related errors
- No extractors matching %r found
- Test case %d not found, got only %d tests
- %s said: %s
- Unable to login: %s
- lynda returned error: %s
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/fc81a7b01c82086d.
Report an issue: GitHub.