librespot icon indicating copy to clipboard operation
librespot copied to clipboard

Authorization request to keymaster returns 403.

Open juliusdelta opened this issue 4 months ago • 36 comments

Look for similar bugs

This just started happening within the past 24 hours but I didn't see any other bugs like it :)

Description

403 Status code is returned from a Mercury request

Version

librespot-connect = { version = "0.6.0", optional = true }
librespot-core = "0.6.0"
librespot-oauth = "0.6.0"
librespot-playback = { version = "0.6.0", optional = true }

This is taken from the spotify-player repo for the version I am on.

How to reproduce

I'm just using spotify-player and sifting through the logs

Log

2025-08-12T18:35:50.330189Z ERROR librespot_core::mercury: error 403 for uri hm://keymaster/token/authenticated?scope=user-read-recently-played,user-top-read,user-read-playback-position,user-read-playback-state,user-modify-playback-state,user-read-currently-playing,streaming,playlist-read-private,playlist-modify-private,playlist-modify-public,playlist-read-collaborative,user-follow-read,user-follow-modify,user-library-read,user-library-modify&client_id=65b708073fc0480ea92a077233ca87bd&device_id=40cd3147-a4c0-4757-8ecb-5875bd3aaa25


2025-08-12T18:35:50.330228Z DEBUG librespot_core::session: could not dispatch command: Service unavailable { error handling Mercury response: MercuryResponse { uri: "hm://keymaster/token/authenticated?scope=user-read-recently-played,user-top-read,user-read-playback-position,user-read-playback-state,user-modify-playback-state,user-read-currently-playing,streaming,playlist-read-private,playlist-modify-private,playlist-modify-public,playlist-read-collaborative,user-follow-read,user-follow-modify,user-library-read,user-library-modify&client_id=xxxxxxx", status_code: 403, payload: [[123, 34, 99, 111, 100, 101, 34, 58, 52, 44, 34, 101, 114, 114, 111, 114, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 58, 34, 73, 110, 118, 97, 108, 105, 100, 32, 114, 101, 113, 117, 101, 115, 116, 34, 125]] } }    

Host (what you are running librespot on):

  • OS: Arch Linux
  • Platform: AMD Ryzen 9
  • Kernal: Linux 6.12.41-1-lts

Additional context

This issue is coming from the spotify-player program. Apologies if this isn't the right place but it seems the error is in the underlying PKCE Authentication flow which seems to be handled exclusively by Librespot.

I checked the Spotify api documentation to ensure that all those scopes being requested still exist and they seem to, however I'm no expert on how flaky they are.

I can provide more info if needed.

juliusdelta avatar Aug 12 '25 19:08 juliusdelta

Related issue in spotify-player repo: https://github.com/aome510/spotify-player/issues/802

juliusdelta avatar Aug 12 '25 19:08 juliusdelta

Just a quick info, don't just blur out the client_id as this is a public info that is required to debug the issue :). I found out through the other issues that the keymaster/offical client_id (65b708073fc0480ea92a077233ca87bd) was used.

photovoltex avatar Aug 12 '25 19:08 photovoltex

For now if you just need an access_token you can acquire one via login5 (available on the Session instance). The token retrieved via login5 has full scope access and is used internally by librespot.

photovoltex avatar Aug 12 '25 19:08 photovoltex

Experiencing the same exact same issue on a Python implementation of this repo. Creating a new set of credentials works but attempting to reuse them leads to a MercuryClient.MercuryException: status: 403. I've looked across several other implementations (Python or otherwise) and they all are reporting similar issues.

Googolplexed0 avatar Aug 13 '25 03:08 Googolplexed0

Trying to use login5 in my case fails with some "Service unavailable" error:

[2025-08-13T06:41:56Z DEBUG librespot::component] new MercuryManager
[2025-08-13T06:41:56Z DEBUG librespot::component] new DealerManager
[2025-08-13T06:41:56Z DEBUG librespot_core::mercury] unknown subscription uri=hm://pusher/v1/connections/NmQwM2FjZjVhYjg2MTBmMmM3ZmRiZWZkNGJiZDQwYmUxNmI4MGE5MitBUCt0Y3A6Ly8wYWIxNTA4Yi5pcC5nZXc0LnNwb3RpZnkubmV0OjUwMDIrRDhGMDE4RUM0NEJCOThGRjVEODg2Mjg3N0Y3NDIxMTFBOTM5N0JDRjJCNjZEM0VBNDhENDNEMEE4OEEwOTZCMg%3D%3D
[2025-08-13T06:41:56Z TRACE librespot_core::mercury] response pushed over Mercury: MercuryResponse { uri: "hm://pusher/v1/connections/NmQwM2FjZjVhYjg2MTBmMmM3ZmRiZWZkNGJiZDQwYmUxNmI4MGE5MitBUCt0Y3A6Ly8wYWIxNTA4Yi5pcC5nZXc0LnNwb3RpZnkubmV0OjUwMDIrRDhGMDE4RUM0NEJCOThGRjVEODg2Mjg3N0Y3NDIxMTFBOTM5N0JDRjJCNjZEM0VBNDhENDNEMEE4OEEwOTZCMg%3D%3D", status_code: 200, payload: [] }
[2025-08-13T06:41:56Z DEBUG librespot_core::session] could not dispatch command: Service unavailable { error handling Mercury response: MercuryResponse { uri: "hm://pusher/v1/connections/NmQwM2FjZjVhYjg2MTBmMmM3ZmRiZWZkNGJiZDQwYmUxNmI4MGE5MitBUCt0Y3A6Ly8wYWIxNTA4Yi5pcC5nZXc0LnNwb3RpZnkubmV0OjUwMDIrRDhGMDE4RUM0NEJCOThGRjVEODg2Mjg3N0Y3NDIxMTFBOTM5N0JDRjJCNjZEM0VBNDhENDNEMEE4OEEwOTZCMg%3D%3D", status_code: 200, payload: [] } }

What other information can I provide to help investigating?

michaelherger avatar Aug 13 '25 06:08 michaelherger

Could someone please come up with an updated examples/get_token.rs using login5 as a POC?

michaelherger avatar Aug 13 '25 06:08 michaelherger

I did a PoC for integrating Login5 in librespot-java here: https://github.com/librespot-org/librespot-java/issues/1099

ltcmdrkeen avatar Aug 13 '25 07:08 ltcmdrkeen

@michaelherger, this (https://github.com/photovoltex/librespot/commit/59d0228a6508f1a3eaf3332948b02b56787881f6) should already do the trick. But I didn't tested it and can only do that in around 12h

photovoltex avatar Aug 13 '25 07:08 photovoltex

Is it worth investigating keymaster issues? What does it provide that login5 doesn't? I'm not keen unless there's a good reason.

If we are going to investigate them please provide the full log we explicitly ask for.

If we are not going to investigate we should deprecate keymaster.

kingosticks avatar Aug 13 '25 08:08 kingosticks

I looked a bit into it yesterday but didn't get too far. What I got from the quick investigation was that we use the ap for way more than the current official desktop client does. So I wouldn't be surprised if the keymaster isn't used anymore, but I couldn't find that out yet.

photovoltex avatar Aug 13 '25 11:08 photovoltex

Is it worth investigating keymaster issues? What does it provide that login5 doesn't? I'm not keen unless there's a good reason.

If we are going to investigate them please provide the full log we explicitly ask for.

If we are not going to investigate we should deprecate keymaster.

Question from a beginner: [core] Add get_token_with_client_id() to get a token for a specific client ID:

get_token_with_client_id() and get_token() are still using keymaster? so how can i get a token for a specific client ID with login5?

or does librespot provide another way to get a token with a client_id that i set as parameter via oauth maybe?

urknall avatar Aug 13 '25 23:08 urknall

In a previous comment I explain the changes necessary. One of them has a commit attached where you can see the changes in action.

photovoltex avatar Aug 14 '25 05:08 photovoltex

You can see the login5 code uses the client id from the session. There are also session methods to change the client id. Does that work? I can't remember. Go try it and tell us.

kingosticks avatar Aug 14 '25 06:08 kingosticks

Oh I missunderstood the question. I think I never tested it with other client_id's. But working with login5 is quite pin pointing, one wrong variable and it would report a generalized error, so I would be supprised if custom id's work.

photovoltex avatar Aug 14 '25 07:08 photovoltex

Oh I missunderstood the question. I think I never tested it with other client_id's. But working with login5 is quite pin pointing, one wrong variable and it would report a generalized error, so I would be supprised if custom id's work.

Me too. I thought it was locked down to Spotify's IDs but might be remembering wrong. Worth trying.

kingosticks avatar Aug 14 '25 07:08 kingosticks

i tried yesterday to manually set the client_id for the session, but i got an error. so i guess only "official" ids are supported.

urknall avatar Aug 14 '25 08:08 urknall

so right now that keymaster isn't working any more (probably depecreated) librespot is not able to get a token for a specific client, that the user has generated in the spotify dashboard?

urknall avatar Aug 14 '25 08:08 urknall

That's annoying if true. But you can just use their client ID for everything you do.... Given how hell-bent they are on screwing over legit devs I see no reason to play by their rules w.r.t this.

kingosticks avatar Aug 14 '25 10:08 kingosticks

you could be running in quota or rate limit problems without your own client_id when doing alot of web api requests.

this could be a way to get a token for your own client_id:

https://developer.spotify.com/documentation/web-api/tutorials/code-pkce-flow

urknall avatar Aug 14 '25 10:08 urknall

I don't understand what you are saying there, but yes, anyone is free to implement the regular Spotify OAuth flow themselves. We are not going to provide a wrapper around that.

Just remember that any client_id obtained from Spotify in the last few months is restricted in terms of endpoint access and quota.

you could be running in quota or rate limit problems without your own client_id when doing alot of web api requests.

I find it extremely doubtful you would hit quota limits using Spotify's special client ID. It's used by millions of people.

kingosticks avatar Aug 14 '25 10:08 kingosticks

i am only refering to the quota modes and rate limits in the spotify api documentation

urknall avatar Aug 14 '25 10:08 urknall

i am only refering to the quota modes and rate limits in the spotify api documentation

This likely has nothing to do with Librespot's interaction with Spotify's servers. Let's see what the next weeks will bring.

michaelherger avatar Aug 14 '25 11:08 michaelherger

after reading the quota and rate limit parts of the api documentation again, you both might be right.

when librespot is using official clients spotify client ids, that should not be a problem.

urknall avatar Aug 14 '25 11:08 urknall

The only thing left to do here is to deprecate keymaster or not. Ideally someone needs to have a quick play and decide if it really is entirely broken now (thanks Spotify) or did the usage requirements change. I don't think any of the Mercury endpoints get any love from Spotify so I'd imagine it's the former. Dumping the official client Mercury traffic might help answer this.

kingosticks avatar Aug 14 '25 11:08 kingosticks

Don’t we still need Mercury to get the track encryption keys? Until we’ve got a clean implementation of the HTTP endpoint for it.

roderickvd avatar Aug 15 '25 07:08 roderickvd

I only meant we could switch out hm://keymaster/token with login5 in TokenProvider. Am I forgetting why that would impact getting track encryption keys?

Although, you raise a good point that working on using the HTTP endpoint for encryption keys would be a good thing to do.

kingosticks avatar Aug 15 '25 14:08 kingosticks

I only meant we could switch out hm://keymaster/token with login5 in TokenProvider. Am I forgetting why that would impact getting track encryption keys?

No, probably my mix-up.

roderickvd avatar Aug 15 '25 14:08 roderickvd

Isn't the HTTP encryption the playplay endpoint, if so... that might be hard to get working as some related project that did revers it got taken down already, see es3n1n/re-unplayplay for example.

photovoltex avatar Aug 15 '25 14:08 photovoltex

after reading the quota and rate limit parts of the api documentation again, you both might be right.

when librespot is using official clients spotify client ids, that should not be a problem.

It is not rate limits spotify is blocking some part of the process but not rate limits. I always use in realtime and have the script set have 5 seconds at least between downloads. Spotify also reached out to my personal email when rates got crazy and put a temp ban on my account.

brzaz228 avatar Aug 15 '25 16:08 brzaz228

Anyone make any progress or any failed attempts they want to update? I tried to alternatively route authentication to web each time for every song but it still didn't work

brzaz228 avatar Aug 21 '25 15:08 brzaz228