(Navidrome) Artists not retrieving images from external provider

Issue description:

The web interface of my navidrome instance retrieves artist images from last.fm and spotify, but in symfonium I only get the gray placeholder image.

Logs:

Upload description: ULJgN

Additional information:

 
Navidrome v 0.54.3
 

Reproduction steps:

 

  • Set up external integrations with navidrome: External Integrations | Navidrome
  • Confirm they work on the web interface, artist images load
  • Open symfonium, sync, go to artist
  • Get default placeholder artist image
     

Media provider:

Subsonic

Screenshots:

     

2025-01-14 09:45:29.104 Error ImageCacheManager  Error downloading image [400] - https://xxx/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600&u=REDACTED&t=REDACTED&s=REDACTED&v=1.13.0&c=Symfonium&f=json

Navidrome returns urls for the image but then errors 400. Navidrome logs probably have details @deluan can help with that.

Yes, please take a look at any errors in Navidrome’s log

@Tolriq, URLs returned by the getArtistInfo and getAlbumInfo are meant to be public, so there’s no need to add subsonic args to it (u, t, c,…)

Yes I know but due to bugs with reverse proxies (You returned the IP of the host not the proper public one, maybe it was fixed) I rewrite the urls and so can also pass any headers or parameters they added to protect the server.

This was fixed, now the user can configure the public URL if ND cannot figure it out automatically.

Ah, I see. Yeah, that makes sense, but if the URL is public, seems that it is a misconfiguration of the proxy, as it should allow access without any authentication

ESC[36mnavidrome_1                      |ESC[0m time="2025-01-14T21:16:43Z" level=warning msg="HTTP: GET http://mynavidrome.com/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600&u=username&t=[REDACTED]&s=[REDACTED]&v=1.13.0&c=Symfonium&f=json" elapsedTime="300.592µs" httpStatus=400 remoteAddr="2a06:3040:12:610::a01e" requestId=navidrome/BA01nqgcN1-002700 responseSize=61

This is after checking an artist that has an artist.jpg in the artist folder, not even an external request. One thing to note, my server doesn’t support http, only https, because my isp blocks port 80 and only allows 443, so maybe that has something to do with it?

Try increasing the log level to debug and posting here more log lines. This one does not say too much.

I don’t think http vs https has anything to do with it.

@Tolriq, there should be a response body in the 400 response, with the actual error. Do you have that in your logs?

ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:02Z" level=debug msg="API: New request /rest/ping.view" client=Symfonium requestId=navidrome/tg6jF88wuR-000015 username=username version=1.13.0
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:02Z" level=debug msg="Found matching player" client=Symfonium id=a98a3d9a-917c-4f11-bef1-c45ddf8fc0b0 requestId=navidrome/tg6jF88wuR-000015 type=Symfonium/Android username=username
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:02Z" level=debug msg="API: Successful response" endpoint=/rest/ping.view requestId=navidrome/tg6jF88wuR-000015 status=OK
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:02Z" level=debug msg="HTTP: GET http://mynavidrome.com/rest/ping.view?u=username&t=[REDACTED]&s=[REDACTED]&v=1.13.0&c=Symfonium&f=json" elapsedTime=4ms httpStatus=200 remoteAddr="2a0d:5600:24:1374::e009" requestId=navidrome/tg6jF88wuR-000015 responseSize=131 userAgent="Symfonium/11.6.0 (Linux;Android 15)"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:04Z" level=warning msg="HTTP: GET http://mynavidrome.com/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600&u=username&t=[REDACTED]&s=[REDACTED]&v=1.13.0&c=Symfonium&f=json" elapsedTime="270.165µs" httpStatus=400 remoteAddr="2a0d:5600:24:1374::e009" requestId=navidrome/tg6jF88wuR-000016 responseSize=61 userAgent="Symfonium/11.6.0 (Linux;Android 15)"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:04Z" level=warning msg="HTTP: GET http://mynavidrome.com/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600&u=username&t=[REDACTED]&s=[REDACTED]&v=1.13.0&c=Symfonium&f=json" elapsedTime="79.683µs" httpStatus=400 remoteAddr="2a0d:5600:24:1374::e009" requestId=navidrome/tg6jF88wuR-000017 responseSize=61 userAgent="Symfonium/11.6.0 (Linux;Android 15)"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:05Z" level=warning msg="HTTP: GET http://mynavidrome.com/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600&u=username&t=[REDACTED]&s=[REDACTED]&v=1.13.0&c=Symfonium&f=json" elapsedTime="253.185µs" httpStatus=400 remoteAddr="2a0d:5600:24:1374::e009" requestId=navidrome/tg6jF88wuR-000018 responseSize=61 userAgent="Symfonium/11.6.0 (Linux;Android 15)"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:05Z" level=warning msg="HTTP: GET http://mynavidrome.com/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600&u=username&t=[REDACTED]&s=[REDACTED]&v=1.13.0&c=Symfonium&f=json" elapsedTime=1.1ms httpStatus=400 remoteAddr="2a0d:5600:24:1374::e009" requestId=navidrome/tg6jF88wuR-000019 responseSize=61 userAgent="Symfonium/11.6.0 (Linux;Android 15)"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="Scheduler: wake" now="2025-01-15 04:25:06.00196785 +0000 UTC"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="Scheduler: run" entry=1 next="2025-01-15 04:26:06 +0000 UTC" now="2025-01-15 04:25:06.00196785 +0000 UTC"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="Scanning folder" folder=/music lastScan="2025-01-15 04:24:06.002003183 +0000 UTC m=+59.435921785"
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="Directory tree loaded from DB" elapsed=64.8ms total=2300
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="Finished reading directories from filesystem" path=/music
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="Finished deleted folders check" elapsed="629.049µs" total=0
ESC[36mnavidrome_1                      |ESC[0m time="2025-01-15T04:25:06Z" level=debug msg="No changes found in Music Folder" elapsed=296.8ms folder=/music

Here’s debug log level right after opening the artist in question with symfonium

logs.txt.json (79.9 KB)
Here are the full navidrome logs, with debug log level and I did a sync in symfonium. I added .json to the filename so I could upload it

I don’t log as it’s supposed to be an image.

Yeah, my bad. I’m used to Subsonic image endpoints that returns a XML response on errors, with status 200!

@ULJgN Unfortunately the logs do not contain any useful info. Is your server publicly available? If so, can you please send me the URL for the image, so I can see the message?

Here’s something interesting: one artist that I manually added an image for was always using a square image, and it loads in symfonium. The artist I’ve been using as an example (which I manually added an image for) was a rectangular image, but I thought maybe that interfered with symfonium loading it so I changed it to a square one, but when I loaded the image on the web interface just now and opened it in a new tab to get the url, it was still the rectangular one. Maybe it’s still cached, and symfonium doesn’t like rectangular images?

That doesn’t account for external integration images not loading in symfonium though

I know you said the u, t, etc flags in the url were unnecessary, but when I open the artist image in a new tab it has u, t, s, f, v, c, and id.

I’m not sure how to get the public url for an artist

Symfonium does not care about the image ratio, the issue here is the error 400.
And yes there’s cache too but only of valid images.

1 Like

The Navidrome UI uses the getCoverArt endpoint for artist images. Symfonium uses the public URL for that.

What I need is for you to tell me what is your server address to put in the image URL bellow (instead of mynavidrome.com):

http://mynavidrome.com/share/img/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFyLWI1MTFjNDkyMTU1NzZmMmZjZjVmNzIyNzhkODI5YzEzXzAiLCJpc3MiOiJORCJ9.7gZ-A5Py6soxjcjBc7LXvm7ns7X-IpP5tluX9bRXHcU?size=600

Ok, I dm’d you with it

Symfonium use the result from getArtistInfo2 when users enable the option to fetch additional metadata.

This was necessary to force servers to do the external source thumbnail fetching and return the possible external images.

When you reworked that endpoint to always return urls then Symfonium had no way to know there’s urls even if there’s nothing on the other side, and so will always use that url as it’s sent by the server so supposed to be valid and better than the coverArt.

How it’s handled on Navidrome side to properly decide what to return on those urls is fully internal to Navidrome.

I’m not saying Symfonium is doing anything wrong, just stating that the two endpoints have this difference: one is public (no need to authenticate) and the other is private. Internally the art resolution is the same.

The only reason the public URL (from getArtistInfo) would return a 400 is if the JWT param is invalid. This could happen because:

  • It was encoded with a different JWT token secret (it changed in 0.54.x)
  • It does not contain an ID or the ID is invalid.

Now thinking more about this, maybe the URL was cached from a previous version of Navidrome, and after the upgrade it is now invalid?

That’s why I’m trying to see the message returned by the 400 error

Ho shit that’s not good at all :frowning:
Yes Symfonium cache those since it requires 1 call per album and artists and it’s insanely slow and inefficient.

And there’s currently no easy way to clear that cache.

:frowning:

The change was required because of this CVE