{"record":{"id":"a32e28c437cd43ca","repo":"ytdl-org/youtube-dl","slug":"s-returned-error-s-a32e28","errorCode":null,"errorMessage":"%s returned error: %s","messagePattern":"(.+?) returned error: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/globo.py","lineNumber":131,"sourceCode":"            if resource_type == 'subtitle':\n                subtitles.setdefault(resource.get('language') or 'por', []).append({\n                    'url': resource_url,\n                })\n                continue\n\n            security = self._download_json(\n                'http://security.video.globo.com/videos/%s/hash' % video_id,\n                video_id, 'Downloading security hash for %s' % resource_id, query={\n                    'player': 'desktop',\n                    'version': '5.19.1',\n                    'resource_id': resource_id,\n                })\n\n            security_hash = security.get('hash')\n            if not security_hash:\n                message = security.get('message')\n                if message:\n                    raise ExtractorError(\n                        '%s returned error: %s' % (self.IE_NAME, message), expected=True)\n                continue\n\n            hash_code = security_hash[:2]\n            padding = '%010d' % random.randint(1, 10000000000)\n            if hash_code in ('04', '14'):\n                received_time = security_hash[3:13]\n                received_md5 = security_hash[24:]\n                hash_prefix = security_hash[:23]\n            elif hash_code in ('02', '12', '03', '13'):\n                received_time = security_hash[2:12]\n                received_md5 = security_hash[22:]\n                padding += '1'\n                hash_prefix = '05' + security_hash[:22]\n\n            padded_sign_time = compat_str(int(received_time) + 86400) + padding\n            md5_data = (received_md5 + padded_sign_time + '0xAC10FD').encode()\n            signed_md5 = base64.urlsafe_b64encode(hashlib.md5(md5_data).digest()).decode().strip('=')","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/globo.py#L113-L149","documentation":"Raised by the Globo extractor when the security-hash endpoint (security.video.globo.com/videos/<id>/hash) returns JSON with no 'hash' but a 'message' — the API's explicit rejection (e.g. resource not entitled, signature expired). Marked expected=True; if there is no message the code just skips the resource.","triggerScenarios":"Requesting a playback hash for a specific resource_id where Globo refuses: unentitled account for that media resource, expired GLBID cookie, or resource removed from the CDN.","commonSituations":"Subscription-tier mismatch (account lacks the package for that resource), stale login cookie after password change, or Globo tightening hash issuance for older videos.","solutions":["Log in again with valid credentials so a fresh GLBID cookie is set","Verify your Globoplay subscription covers the specific video/resource","Update youtube-dl/yt-dlp in case the hash endpoint parameters changed","Try a different quality/resource variant of the same video if available"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import requests\ns = requests.get(f'http://security.video.globo.com/videos/{vid}/hash', params={'player': 'desktop', 'version': '5.19.1', 'resource_id': rid}).json()\nif not s.get('hash'):\n    print('Hash refused:', s.get('message', '(no message)'))","typeGuard":"def hash_issued(security):\n    return isinstance(security, dict) and isinstance(security.get('hash'), str) and len(security['hash']) >= 22","tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept DownloadError as e:\n    if 'returned error' in str(e) and 'glb' in str(e).lower():\n        reauth_and_retry(url)  # usually entitlement/session\n    else:\n        raise","preventionTips":["Keep the GLBID cookie fresh — stale sessions are the top cause of hash refusal","Match subscription tier to content before queueing premium resources"],"tags":["globo","entitlement","api-error","authentication"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}