Description
The screenshot proxy at usercontent.apps.nextcloud.com returns "File not found" (HTTP 200, but body is the literal string File not found instead of image data) for all apps registered since 2026. Older apps work fine.
This causes the Nextcloud admin UI ("Available Apps") to show the gear placeholder icon instead of the app's screenshot, because the Image.onload handler never fires (the response is not a valid image).
Evidence
| App |
Registered |
Proxy Result |
| contacts |
2016-10 |
PNG OK ✅ |
| calendar |
2016-10 |
PNG OK ✅ |
| deck |
2017-02 |
PNG OK ✅ |
| workflow_pdf_converter |
2018-11 |
PNG OK ✅ |
| opsdash |
2026-03-04 |
File not found ❌ |
| linkboard |
2026-03-07 |
File not found ❌ |
| eimzo_sign |
2026-03-12 |
File not found ❌ |
The direct GitHub URLs all work fine (HTTP 200, correct Content-Type: image/png). Only the proxy fails to serve the files.
Steps to Reproduce
# Broken — app registered in 2026:
curl -s "https://usercontent.apps.nextcloud.com/$(echo -n 'https://raw.githubusercontent.com/tschuegy/linkboard-nextcloud/main/img/screenshots/screenshot_GUI.png' | base64 -w0)"
# Returns: "File not found"
# Working — older app:
curl -s "https://usercontent.apps.nextcloud.com/$(echo -n 'https://raw.githubusercontent.com/nextcloud/tasks/master/screenshots/tasks-1.png' | base64 -w0)" | head -c 8 | xxd
# Returns: valid PNG data (89504e47...)
How the screenshot display works (Nextcloud Core)
AppSettingsController::fetchApps() converts screenshot URLs to proxy URLs: https://usercontent.apps.nextcloud.com/{base64(original_url)}
- Frontend (
settings-apps-view-*.js) in mounted(): creates new Image() with the proxy URL
Image.onload sets screenshotLoaded = true → screenshot is displayed
- Since the proxy returns
"File not found" (not a valid image), onload never fires → screenshotLoaded stays false → gear icon is shown
Expected Behavior
The proxy should return the actual image data (fetched from the original URL) with the correct Content-Type header, as it does for older apps.
Affected Nextcloud Versions
All versions — the proxy is an external service, so the Nextcloud server version is irrelevant. The issue affects the admin UI of any Nextcloud instance browsing the app store.
Description
The screenshot proxy at
usercontent.apps.nextcloud.comreturns"File not found"(HTTP 200, but body is the literal stringFile not foundinstead of image data) for all apps registered since 2026. Older apps work fine.This causes the Nextcloud admin UI ("Available Apps") to show the gear placeholder icon instead of the app's screenshot, because the
Image.onloadhandler never fires (the response is not a valid image).Evidence
The direct GitHub URLs all work fine (HTTP 200, correct
Content-Type: image/png). Only the proxy fails to serve the files.Steps to Reproduce
How the screenshot display works (Nextcloud Core)
AppSettingsController::fetchApps()converts screenshot URLs to proxy URLs:https://usercontent.apps.nextcloud.com/{base64(original_url)}settings-apps-view-*.js) inmounted(): createsnew Image()with the proxy URLImage.onloadsetsscreenshotLoaded = true→ screenshot is displayed"File not found"(not a valid image),onloadnever fires →screenshotLoadedstaysfalse→ gear icon is shownExpected Behavior
The proxy should return the actual image data (fetched from the original URL) with the correct
Content-Typeheader, as it does for older apps.Affected Nextcloud Versions
All versions — the proxy is an external service, so the Nextcloud server version is irrelevant. The issue affects the admin UI of any Nextcloud instance browsing the app store.