Good Afternoon!
because there is no answer I have tried to use som artificial intelligence (mine is not sufficient
).
As AI stated there may is a bug in go-librespot : - could you please kindly hav a look?
go-librespot may enters rapid-skip loop after Spotify Connect state PUT timeout (Plugin 4.4.1)
Summary
After a put connect state request to Spotify’s API fails with a timeout, go-librespot loses
synchronization with Spotify Connect and enters an unrecoverable rapid-skip loop, cycling through
multiple tracks in seconds without actually playing them. Volume also resets unexpectedly. The
player does not recover on its own — play/pause buttons still toggle their UI symbols but have no
effect, forward/skip is unresponsive, and no audio is played. The only way to restore
functionality is a full reboot of the device.
Environment
- Volumio 4.103
- Spotify Plugin 4.4.1
- Pi 5, 8GB, NVMe (Samsung SSD 980 500GB)
- HiFiBerry DAC+ Pro, OGG_VORBIS_320
- WLAN connected (stable — plays for hours without issue when the bug doesn’t trigger)
Symptoms
- Playlist plays normally for hours
- After several pause/resume cycles, playback suddenly breaks
- Tracks skip rapidly (each loaded for <200ms, some loaded 3-6x in a row)
- Volume resets to a different value
- UI shows play/pause toggling but no audio output
- No recovery possible without reboot — touch UI responds visually but playback is completely
broken, requiring a full device restart
This happened consistently with 4.3.4 (after ~8-10 pause/resume cycles) and has gotten worse with
4.4.1 (after 2-3 cycles).
Root cause in the logs
I traced the exact failure sequence in journalctl. Here is the complete chain of events from March
28, 2026:
Phase 1 — Normal operation (10:11:39)
Track resumes normally after a ~2h pause:
10:11:39 go-librespot: resume track at 219763ms
10:11:39 go-librespot: put connect state because PLAYER_STATE_CHANGED
10:11:39 go-librespot: emitting websocket event: playing
10:11:39 SPOTIFY: received: {“type”:“playing”, … “resume”:true}
Phase 2 — State PUT fails (10:12:36) ← THE TRIGGER
57 seconds after resume, the state PUT to Spotify’s API times out:
10:12:36 go-librespot: level=error msg=“failed put state after update” error=“context deadline
exceeded”
10:12:36 go-librespot: emitting websocket event: not_playing
10:12:36 go-librespot: loading track (paused: false, position: 1ms)
uri=“spotify:track:360UM2DaiHZPRu0EsrOvMp”
Note: The current track was abandoned immediately. The player jumped to a different track at
position 1ms — the playlist context appears to be lost.
Phase 3 — State corruption confirmed (10:13:24)
The follow-up state request fails with HTTP 400:
10:13:24 go-librespot: level=debug msg=“put state request failed with status 400: Missing payload”
At this point the Spotify Connect state is broken. go-librespot no longer has a valid session
state.
Phase 4 — Rapid-skip loop (10:13:27 – 10:14:00)
go-librespot now cycles through tracks at ~1 track/second, each played for 0-196ms:
10:13:27 loaded “If We Ever Meet Again” (position: 1ms) → pause at 196ms → skip
10:13:28 loaded “Calm After The Storm” (position: 0ms) → skip
10:13:29 loaded “Calm After The Storm” (position: 0ms) → skip ← same track AGAIN
10:13:31 loaded “Calm After The Storm” (position: 0ms) → skip ← and AGAIN
10:13:32 loaded “Calm After The Storm” (position: 0ms) → skip ← 4th time!
10:13:33 loaded “Who Knew” (position: 0ms) → skip
10:13:33 loaded “Lights - Single Version” (position: 0ms) → skip
10:13:35 loaded “Lights - Single Version” (position: 0ms) → skip ← duplicate
10:13:40 loaded “Lights - Single Version” (position: 0ms) → skip ← triplicate
10:13:41 loaded “Lights - Single Version” (position: 0ms) → skip ← 4x
10:13:43 loaded “Lights - Single Version” (position: 0ms) → skip ← 5x
10:13:44 loaded “Lights - Single Version” (position: 0ms) → skip ← 6x!
10:13:50 loaded “Lights - Single Version” (position: 0ms) → skip ← 7x!!
10:13:53 loaded “SexyBack” (position: 0ms) → skip
10:13:55 loaded “SexyBack” (position: 0ms) → skip
10:13:57 loaded “Mi Verdad” (position: 0ms) → skip
10:13:59 loaded “Stupid Love” (position: 0ms)
During this loop, each track triggers resolved context of track → loading track → loaded track →
put connect state → immediately resolved context for the NEXT track. The player never actually
plays audio — it just cycles.
Phase 5 — Volume reset (10:13:59 – 10:14:00)
At the end of the skip loop, unsolicited volume changes arrive:
10:13:59 go-librespot: update volume requested to 14417/65535
10:13:59 go-librespot: update volume requested to 15728/65535
10:14:00 go-librespot: put connect state because VOLUME_CHANGED
This explains why after the incident, the volume is different from what the user set.
Phase 6 — Player is stuck
After the skip loop, the logs show go-librespot still running and responding to pings, but the
player is in a broken state. The UI still responds to touch (play/pause symbols toggle) but no
audio is produced. Forward/skip has no effect. A full device reboot is required to restore
functionality.
Additional context: This is a pattern
The same “failed put state” → desync pattern also occurred on previous days in this boot cycle
(uptime: 8 days, single boot):
Mar 24 13:06:18 level=error “did not receive last pong from dealer, 59s passed”
Mar 24 18:26:48 level=error “did not receive last pong ack from accesspoint, 120s passed”
Mar 27 05:01:07 level=error “failed receiving packet” error=“connection reset by peer”
Mar 28 01:14:29 level=error “did not receive last pong from dealer, 60s passed”
Mar 28 07:11:59 level=error “did not receive last pong from dealer, 60s passed”
Mar 28 09:36:59 level=error “did not receive last pong from dealer, 60s passed”
Mar 28 10:12:36 level=error “failed put state after update” error=“context deadline exceeded” ←
this incident
Mar 28 12:36:29 level=error “did not receive last pong ack from accesspoint, 137s passed”
Analysis
The core issue appears to be that go-librespot has no graceful recovery path when a put connect
state request fails. Instead of retrying the state PUT or pausing playback, it:
- Fires not_playing
- Attempts to load the next track from a (now invalid) context
- Each load triggers another put connect state which may also fail
- This creates a feedback loop of load → state change → context resolve → load next
- After the loop, the player is left in a broken state that cannot be recovered without a reboot
Suggested fix
go-librespot should handle put connect state failures gracefully:
- On timeout (context deadline exceeded): retry the PUT, do not abandon the current track
- On 400 (Missing payload): re-authenticate/re-sync the session state before continuing
- Do not enter a rapid-load loop when state is desynchronized
- If state recovery fails, reset the player to a clean idle state rather than leaving it stuck
Existing log uploads
Thanks for any additional insight.
Warmest regards,
Ralf