{"record":{"id":"208ce188429dbbfa","repo":"ytdl-org/youtube-dl","slug":"giving-up-retrying","errorCode":null,"errorMessage":"Giving up retrying","messagePattern":"Giving up retrying","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/adn.py","lineNumber":227,"sourceCode":"                    })\n                break\n            except ExtractorError as e:\n                if not isinstance(e.cause, compat_HTTPError):\n                    raise e\n\n                if e.cause.code == 401:\n                    # This usually goes away with a different random pkcs1pad, so retry\n                    continue\n\n                error = self._parse_json(\n                    self._webpage_read_content(e.cause, links_url, video_id),\n                    video_id, fatal=False) or {}\n                message = error.get('message')\n                if e.cause.code == 403 and error.get('code') == 'player-bad-geolocation-country':\n                    self.raise_geo_restricted(msg=message)\n                raise ExtractorError(message)\n        else:\n            raise ExtractorError('Giving up retrying')\n\n        links = links_data.get('links') or {}\n        metas = links_data.get('metadata') or {}\n        sub_url = (links.get('subtitles') or {}).get('all')\n        video_info = links_data.get('video') or {}\n        title = metas['title']\n\n        formats = []\n        for format_id, qualities in (links.get('streaming') or {}).items():\n            if not isinstance(qualities, dict):\n                continue\n            for quality, load_balancer_url in qualities.items():\n                load_balancer_data = self._download_json(\n                    load_balancer_url, video_id,\n                    'Downloading %s %s JSON metadata' % (format_id, quality),\n                    fatal=False) or {}\n                m3u8_url = load_balancer_data.get('location')\n                if not m3u8_url:","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/adn.py#L209-L245","documentation":"Raised by multipart_encode/_multipart_encode_impl when the chosen multipart boundary string appears inside a form field's name or value, which would corrupt the framing (a receiver would split the body at the wrong place). The library deliberately scans each encoded part for the boundary bytes and aborts rather than emitting an ambiguous body.","triggerScenarios":"Calling multipart_encode(data, boundary=...) with a boundary that is a substring of any value (or field name) in data. With a random default boundary this is astronomically unlikely; it happens when callers pass a fixed/short boundary like 'boundary' or '----x' and upload text content containing that token.","commonSituations":"Reusing a hard-coded boundary from a captured browser request whose body content later includes the same string; very short boundaries colliding with binary-ish payloads; API clients mirroring a server's expected boundary without validating against content.","solutions":["Omit the boundary argument and let multipart_encode generate a random one (it uses uuid-based generation).","Use a long, high-entropy boundary (e.g. '----------aBcXyZ1234567890$') unlikely to occur in any field.","If the server requires an exact boundary, sanitize or base64-encode field values that might contain it.","Catch ValueError at the call site and regenerate a new random boundary before retrying once."],"exampleFix":"# before\nbody, ct = multipart_encode(data, boundary='----WebKitFormBoundaryx')\n\n# after: auto-generate a collision-free boundary\nbody, ct = multipart_encode(data)  # random uuid4-based boundary\n\n# or regenerate on collision\nimport uuid\nwhile True:\n    try:\n        body, ct = multipart_encode(data, boundary=uuid.uuid4().hex)\n        break\n    except ValueError:\n        continue","handlingStrategy":"retry","validationCode":"import uuid\n\ndef safe_multipart_encode(data, boundary=None):\n    from youtube_dl.utils import multipart_encode\n    for _ in range(5):\n        b = boundary or uuid.uuid4().hex\n        collisions = [k for k, v in data.items() if b.encode('ascii')\n                      in str(k).encode('utf-8') + str(v).encode('utf-8')]\n        if not collisions:\n            return multipart_encode(data, boundary=b)\n        boundary = None  # regenerate\n    raise ValueError('could not find a non-colliding boundary')","typeGuard":null,"tryCatchPattern":"from youtube_dl.utils import multipart_encode\nimport uuid\nfor _ in range(5):\n    try:\n        body, ct = multipart_encode(data, boundary=uuid.uuid4().hex)\n        break\n    except ValueError as e:\n        if 'Boundary overlaps with data' not in str(e):\n            raise\nelse:\n    raise ValueError('boundary kept colliding with payload')","preventionTips":["Let the library generate a random boundary instead of passing a fixed one.","Never reuse a boundary captured from a browser request with arbitrary user content.","Prefer long high-entropy boundaries (uuid4().hex) — collisions become impossible in practice."],"tags":["http","multipart","validation","upload"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}