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

  1. Use the exact extractor name: youtube-dl --list-extractors, then pass that name verbatim, e.g. testurl:ExactName (exact case-insensitive match disambiguates automatically).
  2. Anchor the regex if you intended one extractor: testurl:^vimeo$.
  3. 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

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


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/fc81a7b01c82086d. Report an issue: GitHub.