Repository navigation
Description
Context
- Add-on Version: 7.4.4 (from repository.xbmc.org)
- Kodi Version: 21.3 (21.3.0) Git:21.3-Omega, Linux ARM 64-bit
- Kodi GUI Language: German (de_DE)
- Operating System: LibreELEC 12.2.1 on Raspberry Pi 5, kernel 6.12.56
- Operating System Language: German
- inputstream.adaptive: 21.5.22.1
- Not signed in to the add-on (own API key/OAuth credentials configured, but no account authorised)
Expected Behavior
Video plays through to the end.
Current Behavior
Playback starts, runs for roughly 10-15 seconds, then stops and returns to the listing.
The add-on's stream proxy receives 403 Forbidden from the googlevideo servers. The pattern is consistent: the initial range requests succeed, but every request for a byte range beyond roughly the first 60 seconds of the audio stream fails. inputstream.adaptive retries six times and gives up, which tears down the player well before playback actually reaches the 60 second mark.
All failing requests are made with Client: 28 (ANDROID_VR).
Over one affected session, 250 responses were 403 Forbidden and 26 were 400 Bad Request; the 400s appear when the add-on follows a Target: redirect to a different googlevideo host.
Affected itags were 140 (audio, mp4a) and 397 (video, AV1). Three different videos were affected in the same session, so it is not content specific.
Steps to Reproduce
- Start any video from a channel listing or search result.
- Playback begins normally.
- After ~10-15 seconds playback stops and Kodi returns to the previous screen.
Log
I am aware the template asks for a complete debug log, and I am sorry that I cannot supply one: debug logging was not enabled while the problem was occurring, and the problem has since stopped on its own without any change on my side. I would rather file this now than sit on it, because the relevant lines seem unambiguous and the timing lines up with a known upstream change (see below). I will turn on debug logging and verbose add-on logging and attach a full log immediately if it recurs.
Excerpt from kodi.log (public IP redacted, 127.0.0.1 is the add-on's own proxy):
2026-08-14 14:52:59.550 T:8676 warning <general>: [plugin.video.youtube] http_server:537(do_GET)
Stream proxy response not OK
Stream: ('<video-id>', '140') - ('audio', 'mp4')
Method: 'POST'
Server: 'rr2---sn-u1i5h5-5q.googlevideo.com'
Target: 'rr5---sn-5hne6nz6.googlevideo.com'
Status: 403 Forbidden
Client: 28 (ANDROID_VR)
Range: 'bytes=980184-1141774' (~60.57s)
2026-08-14 14:52:59.661 T:8676 warning <general>: [plugin.video.youtube] http_server:537(do_GET)
Stream proxy response not OK
Stream: ('<video-id>', '140') - ('audio', 'mp4')
Method: 'POST'
Server: 'rr5---sn-5hne6nz6.googlevideo.com'
Target: None
Status: 400 Bad Request
Client: 28 (ANDROID_VR)
Range: 'bytes=980184-1141774' (~60.57s)
Corresponding traceback:
Traceback (most recent call last):
File ".../youtube_plugin/kodion/network/requests.py", line 442, in request
response.raise_for_status()
File ".../script.module.requests/lib/requests/models.py", line 1021, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url:
https://rr5---sn-5hne6nz6.googlevideo.com/videoplayback?...&itag=140&...&c=ANDROID_VR&...
And the resulting inputstream.adaptive failure:
error <general>: AddOnLog: inputstream.adaptive: [AS-17] Download failed, HTTP error 403:
http://127.0.0.1:50152/youtube/stream?...&itag=140&...
warning <general>: AddOnLog: inputstream.adaptive: [AS-17] Segment download failed, attempt 2...
[... attempts 3 through 6 ...]
info <general>: CVideoPlayer::OnExit()
There are no LOGIN_REQUIRED or "Sign in to confirm you're not a bot" entries anywhere in the log, and no VPN, proxy or custom DNS is in use.
Additional Information
This looks like it may be the same change yt-dlp documented on 2026-08-02 in yt-dlp/yt-dlp#17348: the android_vr client now requires a GVS PO token for everything except format 18, and without it the video servers return 403. The symptom described there — initial data is served, then 403 — matches what I see.
As far as I can tell from reading the source, the add-on has no PO token handling (only visitorData), so I assume there is no configuration on my side that would work around this.
One secondary observation while trying to work around it locally, in case it is useful: in _process_adaptive_streams, streams are written with
mime_group[itag] = quality_group[itag] = detailswithout checking whether the itag is already present, so a later client group overwrites the URLs of earlier ones. Since android_vr is the last entry in _client_groups, its URLs win for every itag it provides — including audio itag 140. That is why restricting the stream features (for example disabling AV1 so that itag 397 is not selected) does not help: the audio URL still comes from android_vr and still fails. The HLS path at lines ~1226 and ~1264 does guard with if itag in stream_list: continue, so the behaviour differs between the two paths.
Happy to test any patch or test build, and to provide a full debug log if it comes back.
Activity
popcornmix commentedon Aug 14, 2026
I've been hitting this. Often stops after 30s or 60s.
But intermittent, sometimes the same video plays to the end.
Caught in a debug log.
BehnK commentedon Aug 17, 2026
I can confirm that Serph91P's fix has worked with this issue on my Kodi Omega intallation of 7.4.4
Marxiboy commentedon Aug 19, 2026
I also confirm this fixed my Khadas Vim 4 21.3.
lbriais commentedon Aug 19, 2026
Same issue here, sometimes it works and most of the times it fails...
I got the exact same error messages, seeing the exact same:
The point is... this is not kodi for android... this a linux box (osmc)... Thus I doubt I will be able to "refresh the android vr client profile"...
AIsNeverDie commentedon Aug 19, 2026
"android_vr" is dead.
lbriais commentedon Aug 19, 2026
Ok my bad, I finally understood this android stuff was just display, and reading the PR from Serph91P I just had to patch a single file to update the client definition (not the client)...
And yes as weird as it sounds it fixed the issue !! Thanks Serph91P 👍 !
Hopefully it will eventually make its way to the next release to avoid having to patch it again !
bierbaron2 commentedon Aug 19, 2026
I'm using 7.2.0+beta.5 (because I don't like the short videos to be separated) and the fix isn't working. Can somebody please provide a fix for this version?
It works with 7.4.4
repitah commentedon Aug 21, 2026
See the patched file in the pull request: #1482
RobjSky commentedon Aug 22, 2026
I applied Serph91P's fix and it has worked for me. Youtube is running fine again on Nvidia Shield with Omega and addon 7.4.4
calvin4242 commentedon Aug 25, 2026
Thank you 👍it works for me with 21.3 Omega and addon 7.4.4
mrfoobar1 commentedon Aug 27, 2026
I applied the fix on 21.3 Omega and addon 7.4.4 and it fix the issue!
rsantellan commentedon Aug 28, 2026
I applied the fix on 21.2-Omega with 7.4.4 and it also fix it! Thank you very much!
CarstenG2 commentedon Aug 30, 2026
Measurements on the 403 cutoff, plus a note on why #1482 works
Confirming this on 7.4.4 / Kodi 21.3 / inputstream.adaptive 21.5.23 (Windows x64, not signed in). I measured the cutoff outside of Kodi and ended up with a result that may be worth knowing before #1482 is merged, because the mechanism looks different from what the PR assumes.
1. The cutoff is a fixed position in the stream
Requesting the audio stream directly with the client's own headers and bisecting the byte offset at which GVS switches from
206to403:Three different file sizes and durations, but the cutoff lands at roughly 76 seconds every time. On the higher-bitrate audio track (itag 140) it was ~70s.
What does not matter: the
ipbound into the signed URL (it matched), the request headers,Origin/Referer, GET vs POST, and the start of the requested range.bytes=970768-987151returns206, whilebytes=970768-1132492returns403— only how far the range reaches into the stream decides it.2. Why the picture freezes while audio keeps playing
From a debug log, the order of events is:
403, retries six times, gives up.CDVDVideoCodecFFmpeg::GetPicture - eof hw accel, immediately followed byCVideoPlayerVideo - Stillframe detected.ActiveAE - large audio sync errorgrows 1:1 with wall clock.So audio is what actually breaks, but a frozen picture is what users see first.
3. #1482 fixes it, but not for the stated reason
The PR assumes the refreshed
ANDROID_VRprofile yields usable stream URLs again. In my measurements it does not: with the Pico 4 identity the player response comes back withserverAbrStreamingUrland adaptive formats carrying neitherurlnorsignatureCipher— SABR delivery, unusable for the add-on. Forcing a URL out of it and requesting past the cutoff still returns403.What actually changes is the fallthrough:
c=ANDROID_VRc=ANDROIDThe client that ends up serving is
android_testsuite_params. So the PR works by makingandroid_vrfail cleanly rather than by repairing it.4. Profile matrix
Every profile in
request_client.py, with and without the player params, headers and body rendered from the templates in the file:android8AEBandroid2AMBandroid_testsuite_params2AMBiosios2AMBios_testsuite_params2AMBandroid_vr(Pico)android_vr(Pico)2AMBtv,tv_unplugged,tv_embed,web,v1,mwebandroid_youtube_tv,ios_youtube_tvandroid_testsuite2AMBandroid_embeddedTwo pairs isolate the cause, since only the params value differs within each pair:
androidfails with8AEBand plays through completely with2AMB.iostruncates without params and plays through completely with2AMB.So the deciding factor is
params=2AMB, not the user agent or the client id. No profile delivers a complete stream without it. Andandroid_vrcannot be rescued even with2AMB— the VR loophole looks closed rather than stale.5. Suggestion
If the VR profile no longer yields usable URLs on any identity, dropping it from the candidate list is more direct than swapping in another headset, and it states the intent:
The group keeps an empty tuple, matching the existing
('mpd', ())and('ask', ())entries, andrequest_client.pystays untouched.I ran both variants against the same video. Identical outcome: full 157s playback, clean
OnPlayBackEnded, video track complete (23964578 / 23964579 bytes), audio track complete (2533042 / 2533043 bytes), zeroStillframe detected, zero sync errors, zero 403s in the stream proxy. Both end up onandroid_testsuite_params.6. One thing worth flagging
Everything now rests on
params=2AMB. Decoded it is a tiny protobuf:A single flag, differing only in field number. If that one gets restricted too, neither a profile swap nor a fresh identity will help — so it may be worth treating
ios_testsuite_paramsas an explicit backup, since it also delivers complete streams and is already in the candidate list.Happy to open a PR for the removal if that direction is preferred.
Fludizz commentedon Aug 30, 2026
@CarstenG2 the action of removing (or commenting out) the 'android_vr' line might fix the playback issue, however, it does introduce a new issue: Updating the Watch History in your Youtube account breaks, as I mentioned in #1483 (comment)
fix: bump yt-dlp to 2026.8.19 to fix seek 403 on android_vr client (#9)
willheisenberg commentedon Sep 10, 2026
Follow-up from the reporter: it came back on 2026-09-04 on the same setup
(Raspberry Pi 5, LibreELEC 12.2.1, Kodi 21.3, add-on 7.4.4,
inputstream.adaptive 21.5.24.1, not signed in). Same pattern: tv/tv_unplugged
fail with UNPLAYABLE, ANDROID_VR URLs return 403 after a few seconds.
Commenting out 'android_vr' in _client_groups (player_client.py) fixed it.
No 403s or inputstream.adaptive download failures in the logs since 2026-09-08.
As I'm not signed in, I can't confirm anything regarding the watch history
side effect from #1483. Happy to test the
_use_adaptive: Falsevariantsuggested in #1482 if that helps.