Description
GET /avatarproxy/:jellyfinUserId never sends a response when the path parameter
fails the 32-hex validation check. The request hangs until the client or an
upstream proxy times out.
In server/routes/avatarproxy.ts, the handler throws when the parameter does not
match /^[a-f0-9]{32}$/, and the catch block logs the error but never calls
res:
} catch (e) {
logger.error('Failed to proxy avatar image', {
errorMessage: e.message,
});
}
Since nothing is sent and next(e) is not called, Express keeps the request open
indefinitely. The route is mounted outside /api/v1 (server/index.ts), so it is
not covered by the OpenAPI validator and requires no authentication — an
unauthenticated request can hold a server connection open with no rate limit.
Behind a reverse proxy this surfaces as a gateway timeout (Cloudflare returns 524
after 100s).
Still present on develop as of this report.
Suggested fix
Send a response on the error path, e.g.:
} catch (e) {
logger.error('Failed to proxy avatar image', {
errorMessage: e.message,
});
if (!res.headersSent) {
res.status(400).send('Invalid avatar request');
}
}
Returning 404 instead of 400 would be equally reasonable. Validating the parameter
before entering the try block would also work.
Version
3.4.1
Steps to Reproduce
- Run any Seerr instance.
curl -m 15 -o /dev/null -w '%{http_code} %{time_total}\n' http://<host>:5055/avatarproxy/1
- Observe no response — curl reports
000 at the timeout instead of a status code.
- For contrast,
curl http://<host>:5055/avatarproxy/00000000000000000000000000000000
returns 200 with an image in well under a second.
Any value that is not exactly 32 lowercase hex characters reproduces it
(/avatarproxy/abc, /avatarproxy/1, etc.).
Note: this reproduces regardless of media server type. It was found on a
Plex-backed instance, where /avatarproxy is never used by the frontend at all —
those URLs are only generated for Jellyfin/Emby users — so the endpoint is
reachable and hangs even on installs that have no use for it.
Screenshots
No response
Logs
2026-09-08T01:32:32.635Z [error][API]: Failed to proxy avatar image {"errorMessage":"Provided URL is not an Emby avatar."}
$ curl -m 15 -o /dev/null -w 'HTTP %{http_code} after %{time_total}s\n' http://127.0.0.1:5055/avatarproxy/1
HTTP 000 after 15.001360s
$ curl -m 15 -o /dev/null -w 'HTTP %{http_code} after %{time_total}s\n' http://127.0.0.1:5055/avatarproxy/00000000000000000000000000000000
HTTP 200 after 0.009405s
Platform
desktop
Database
SQLite (default)
Device
Desktop PC
Operating System
Windows 11
Browser
Chrome 152
Additional Context
No response
Search Existing Issues
Code of Conduct
Description
GET /avatarproxy/:jellyfinUserIdnever sends a response when the path parameterfails the 32-hex validation check. The request hangs until the client or an
upstream proxy times out.
In
server/routes/avatarproxy.ts, the handler throws when the parameter does notmatch
/^[a-f0-9]{32}$/, and thecatchblock logs the error but never callsres:Since nothing is sent and
next(e)is not called, Express keeps the request openindefinitely. The route is mounted outside
/api/v1(server/index.ts), so it isnot covered by the OpenAPI validator and requires no authentication — an
unauthenticated request can hold a server connection open with no rate limit.
Behind a reverse proxy this surfaces as a gateway timeout (Cloudflare returns 524
after 100s).
Still present on
developas of this report.Suggested fix
Send a response on the error path, e.g.:
Returning 404 instead of 400 would be equally reasonable. Validating the parameter
before entering the
tryblock would also work.Version
3.4.1
Steps to Reproduce
curl -m 15 -o /dev/null -w '%{http_code} %{time_total}\n' http://<host>:5055/avatarproxy/1000at the timeout instead of a status code.curl http://<host>:5055/avatarproxy/00000000000000000000000000000000returns
200with an image in well under a second.Any value that is not exactly 32 lowercase hex characters reproduces it
(
/avatarproxy/abc,/avatarproxy/1, etc.).Note: this reproduces regardless of media server type. It was found on a
Plex-backed instance, where
/avatarproxyis never used by the frontend at all —those URLs are only generated for Jellyfin/Emby users — so the endpoint is
reachable and hangs even on installs that have no use for it.
Screenshots
No response
Logs
2026-09-08T01:32:32.635Z [error][API]: Failed to proxy avatar image {"errorMessage":"Provided URL is not an Emby avatar."} $ curl -m 15 -o /dev/null -w 'HTTP %{http_code} after %{time_total}s\n' http://127.0.0.1:5055/avatarproxy/1 HTTP 000 after 15.001360s $ curl -m 15 -o /dev/null -w 'HTTP %{http_code} after %{time_total}s\n' http://127.0.0.1:5055/avatarproxy/00000000000000000000000000000000 HTTP 200 after 0.009405sPlatform
desktop
Database
SQLite (default)
Device
Desktop PC
Operating System
Windows 11
Browser
Chrome 152
Additional Context
No response
Search Existing Issues
Code of Conduct