{"record":{"id":"548951b4bec5d004","repo":"ytdl-org/youtube-dl","slug":"reason-dynamic-youtube-playability-status-reason","errorCode":null,"errorMessage":"reason (dynamic YouTube playability status reason, with optional subreason/captcha suffix)","messagePattern":"reason \\(dynamic YouTube playability status reason, with optional subreason/captcha suffix\\)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/youtube.py","lineNumber":2807,"sourceCode":"            reason = get_text(pemr.get('reason')) or playability_status.get('reason') or ''\n            subreason = pemr.get('subreason')\n            if subreason:\n                subreason = clean_html(get_text(subreason))\n                if subreason.startswith('The uploader has not made this video available in your country'):\n                    countries = microformat.get('availableCountries')\n                    if not countries:\n                        regions_allowed = search_meta('regionsAllowed')\n                        countries = regions_allowed.split(',') if regions_allowed else None\n                    self.raise_geo_restricted(\n                        subreason, countries)\n                reason += '\\n' + subreason\n\n            if reason:\n                if 'sign in' in reason.lower():\n                    self.raise_login_required(remove_end(reason, 'This helps protect our community. Learn more'))\n                elif traverse_obj(playability_status, ('errorScreen', 'playerCaptchaViewModel', T(dict))):\n                    reason += '. YouTube is requiring a captcha challenge before playback'\n                raise ExtractorError(reason, expected=True)\n\n        self._sort_formats(formats)\n\n        keywords = video_details.get('keywords') or []\n        if not keywords and webpage:\n            keywords = [\n                unescapeHTML(m.group('content'))\n                for m in re.finditer(self._meta_regex('og:video:tag'), webpage)]\n        for keyword in keywords:\n            if keyword.startswith('yt:stretch='):\n                mobj = re.search(r'(\\d+)\\s*:\\s*(\\d+)', keyword)\n                if mobj:\n                    # NB: float is intentional for forcing float division\n                    w, h = (float(v) for v in mobj.groups())\n                    if w > 0 and h > 0:\n                        ratio = w / h\n                        for f in formats:\n                            if f.get('vcodec') != 'none':","sourceCodeStart":2789,"sourceCodeEnd":2825,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/youtube.py#L2789-L2825","documentation":"The dynamic playability-status failure in YoutubeIE._real_extract: when no formats were obtained and no DRM licenseInfos exist, the extractor builds 'reason' from playability_status (errorScreen.playerErrorMessageRenderer.reason or playability_status.reason), optionally appends a cleaned subreason, escalates geo-restriction via raise_geo_restricted or login via raise_login_required (when 'sign in' appears), notes captcha challenges, and finally raises ExtractorError(reason, expected=True). The message is whatever YouTube reported.","triggerScenarios":"Videos with playabilityStatus.status like UNPLAYABLE/LOGIN_REQUIRED/ERROR: private videos, removed videos, sign-in-required (age) videos, country-locked videos (subreason starting 'The uploader has not made this video available in your country'), and captcha challenges (playerCaptchaViewModel).","commonSituations":"Age-restricted videos without login; region locks for users in blocked countries; members-only or private uploads; YouTube occasionally forcing captchas on datacenter IPs.","solutions":["Read the reason text — it is YouTube's own explanation and dictates the fix.","For sign-in/age reasons, pass cookies: --cookies-from-browser or --username/--password.","For geo blocks, route through an allowed region or accept the restriction; availableCountries/microformat informs which.","For captchas, slow down / use residential egress; for removed/private, no client-side fix exists."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def playability_is_fatal(player_response: dict) -> bool:\n    status = traverse_obj(player_response, ('playabilityStatus', 'status'))\n    return status in ('UNPLAYABLE', 'LOGIN_REQUIRED', 'ERROR')","tryCatchPattern":"try:\n    info = ydl.extract_info(url)\nexcept ExtractorError as e:\n    msg = str(e)\n    if 'sign in' in msg.lower() or 'confirm your age' in msg.lower():\n        retry_with_cookies(url)          # LOGIN_REQUIRED / age gate\n    elif 'not made this video available in your country' in msg:\n        skip_or_reroute_region(url)      # geo block\n    else:\n        raise","preventionTips":["Supply cookies up front for age-gated and members-only content instead of reacting to failures.","Classify on the reason text (sign in / country / captcha) — each has a different remedy."],"tags":["youtube","playability","geo-restricted","login-required","dynamic-message"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}