Skip to content

v5.2: YouTube, SABR, VISITORDATA and 403 #2820

Description

@InfinityLoop1308

TL;DR

  • Starting from v5.2.5, playback endpoints are reverted: not signed in → android_vr (same as NewPipe), signed in → tv_downgraded
  • SABR playback is temporarily disabled; the implementation is preserved in the codebase
  • Reason: the visitorData / PO Token verification that SABR relies on is being probabilistically rejected server-side — success rates fluctuate between 30% and 70% per video depending on IP and local time, making playback unreliable
  • android_vr also encounters 403 errors randomly, but at a failure rate of roughly 5% or lower
  • tv_downgraded (signed-in) does not exhibit 403 errors

Why so many releases in one month?

We were not shipping broken code over and over. YouTube has been tightening playback restrictions continuously, and we were chasing a moving target. Here is what happened:

Timeline

Version / Period What happened
After 5.1.1 Sporadic 403 reports on the android_vr endpoint began appearing
5.2.0 Experimental SABR support added; main playback path remained android_vr
Days after 5.2.0 403 reports on android_vr became noticeably more frequent. Meanwhile, web_safari — the other endpoint in use — was also approaching failure. We concluded that a swift transition to SABR was necessary
5.2.2 Main playback path switched to SABR, with the ability to fall back to android_vr retained
5.2.3 With SABR now serving all users, the volume of requests exposed many more edge cases and a significant performance regression. This release fixed most edge cases and substantially improved performance. Further reports after release allowed us to resolve the remaining edge cases and optimize performance further
5.2.4 SABR implementation was essentially complete — virtually no edge-case issues remained. At the time of release, playback worked near-perfectly
Days after 5.2.4 A new symptom appeared: playback increasingly hit an infinite error loop around the 1-minute mark. This was not an implementation bug (see below)
5.2.5 beta Tested visitorData / PO Token implementations from yt-dlp, googlevideo, LibreTube, SmartTube, Grayjay, and others — none achieved a 100% success rate
5.2.5 (imminent) Playback endpoints reverted to android_vr / tv_downgraded

What does "1-minute error loop" actually mean?

SABR responses carry a playback status field:

Status Meaning Practical effect
1 OK Full stream can be fetched
2 Pending attestation Already a precursor to rejection — only the first ~60 seconds of the stream are served
3 Rejected Stream cannot be fetched at all

When the server returns status 2, playback appears to work at first, but the moment it reaches the 60-second boundary — or if the user seeks past 60 seconds from the start — it immediately escalates to status 3. The user sees the player stuck at roughly the 1-minute mark, retrying and failing in a loop.

The end result is effectively identical to the old 403 problem (only the first ~60 seconds are accessible). The difference is that android_vr does not require a PO Token at all, and its failure rate is far lower.

This is not a bug in our SABR implementation. The server is rejecting our requests. When 5.2.4 was first released, status 2/3 responses were virtually nonexistent; within days, their frequency increased significantly.


The problem is visitorData, but we don't know the exact mechanism

Success rates vary by IP address and local time. For the same video, the probability of getting status 1 ranges from roughly 30% to 70%, and this variance is governed by the visitorData token.

During the 5.2.5 beta cycle we evaluated every notable public implementation of visitorData / PO Token generation we could find — yt-dlp, googlevideo, LibreTube, SmartTube, Grayjay, among others. Not a single one guarantees 100% success. We suspect YouTube has introduced a verification step that has not yet been publicly analyzed, and is using probabilistic failure to impede reverse-engineering efforts. As of this writing, the broader community has not found a solution.

Technical details: visitorData, the WebPO minter, and video-bound tokens

“The problem is visitorData” does not mean that PipePipe mints the final SABR media PO Token with visitorData as its content binding.

There are two separate stages:

visitorData
    │
    ├── included in the `/youtubei/v1/att/get` context
    ├── sent as `X-Goog-Visitor-Id`
    └── identifies the attestation/minter epoch
    │
    ▼
BotGuard challenge
    │
    ▼
BotGuard snapshot
    │
    ▼
WAA integrity token
    │
    ▼
WebPO minter associated with that visitor identity
    │
    │ mint(contentBinding = videoId)
    ▼
video-bound SABR media PO Token

PipePipe already uses the video ID as the content binding of the final media token. However, that token is minted by a minter created through an attestation chain whose identity starts with visitorData. Replacing visitorData therefore recreates the challenge, integrity token, minter, and all tokens minted from that minter.

Variants tested

Component Variants tested Result
visitorData source Obtained through /youtubei/v1/att/get No improvement
visitorData source Parsed from a youtube.com response No improvement
visitorData lifetime Reuse one identity for its stated 6-hour lifetime No improvement
visitorData lifetime Use a new identity for every request No improvement
PO Token binding Always mint with videoId No improvement
PO Token binding Choose visitorData or videoId according to the token-binding experiment flag returned by youtube.com No improvement

None of these visitorData acquisition, persistence, or PO Token content-binding strategies improved the acceptance rate.

Observed acceptance behavior

Acceptance is not a permanent property of a visitorData value or even of a specific (visitorData, PO Token) pair:

visitorData V
    │
    ├── minter V ── mint(videoId X) ── token PX
    │                                  │
    │                                  ├── request at T1: status 2 / 3
    │                                  └── request at T2: may succeed
    │
    └── same minter or identity
          └── mint(videoId Y) ── token PY
                                  └── probabilistic again

A visitorData identity accepted for one video therefore does not reliably carry that acceptance to the next video. Conversely, a previously rejected visitorData/token combination may be accepted when retried later.

Once a combination is accepted for a playback and playback crosses the 60-second boundary, we have not observed it being rejected later in that same playback. The decision appears to be sticky for the accepted playback, but not for the visitor identity as a whole.

Status 2 behavior

PipePipe already provides a real video-bound PO Token when status 2 is returned. In our environment, status 2 only permits approximately the first minute of media. Reaching or seeking beyond that boundary causes status 3, after which playback cannot continue.

status 1 ──> full playback remains available

status 2 ──> first ~60 seconds
                │
                └── reach/seek beyond boundary
                        └── status 3

The only environment in which we have observed status 2 being promoted to status 1 is a real Chrome session. We could not reproduce that transition in headless Chrome or in a Chrome session controlled through Playwright.

This suggests that the unresolved part is an additional verification condition in the visitorData-rooted attestation chain, not the already implemented video-ID content binding.


The decision

The comparison is straightforward:

Endpoint Approximate success rate PO Token required
SABR 30–70% Yes (visitorData)
android_vr / vision_os (not signed in) ~95% No
tv_downgraded (signed in) ~100% No

For the sake of playback reliability, we are temporarily reverting to the latter two.

The SABR implementation remains in the codebase. Once the community figures out the visitorData verification, we can switch back quickly — the work done this month will not go to waste.


What you need to do

Update to v5.2.5 once it is released. No additional configuration is needed.


If you have technical insights

Reproducing the status 2/3 failure is straightforward and does not require special conditions, so simple reproduction reports are not particularly useful at this point. What would help is information about the underlying verification mechanism — if you have insights into how YouTube validates visitorData or PO Tokens in SABR streams, please share them in this issue.


Looking ahead

android_vr is not a long-term solution — YouTube continues to tighten its restrictions, and SABR remains the protocol it is moving toward. We are still actively experimenting on our end. Once a breakthrough emerges — whether from our own efforts or from others — we will be ready to switch back quickly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions