Version
2.3.2 (also affects 2.2.x, 2.3.0, 2.3.1)
Description
When uploading images to an asset folder and viewing them in the Preview tab, thumbnails that haven't been generated yet show a loading spinner (video-loading.gif) that never resolves, even after the thumbnail has been generated by the messenger worker. The spinner persists until the user does a hard browser refresh (Ctrl+F5) or switches to the List view.
Root Cause
Two issues in AssetController::getImageThumbnailAction() at line 1179-1181:
1. Placeholder response is cacheable
When origin=folderPreview and the thumbnail doesn't exist yet, the controller returns video-loading.gif as a BinaryFileResponse without Cache-Control: no-store headers. The browser caches this response.
The getFolderContentPreviewAction generates thumbnail URLs using the asset's modificationDate as the _dc cache-buster parameter (e.g. _dc=1774887063). Since this timestamp never changes for the same asset, subsequent requests hit the browser cache and serve the cached spinner forever.
2. No async thumbnail generation is dispatched
For origin=treeNode, the controller dispatches AssetPreviewImageMessage to trigger async thumbnail generation. But for origin=folderPreview, no message is dispatched — the thumbnail is only generated if/when the pimcore_asset_update worker processes it independently.
Steps to Reproduce
- Open the Pimcore admin UI
- Create a new asset folder
- Upload 5-6 images (e.g. JPEG, 3-600KB each)
- Open the folder → click Preview tab
- Observe: some images show the loading spinner, others may show correctly (depends on timing)
- Wait 30+ seconds (worker generates thumbnails)
- Reload the page → spinners persist
- Switch to List view → all thumbnails display correctly
Why List view works
The List view uses a different URL pattern:
/admin/asset/get-image-thumbnail?id=1429852&treepreview=1&width=108&height=70&frame=1
The Preview (folder) view uses:
/admin/asset/get-image-thumbnail?id=1429852&treepreview=1&_dc=1774887063&origin=folderPreview
Different URL = no cached stale response in the browser.
Current code
https://github.com/pimcore/admin-ui-classic-bundle/blob/2.3/src/Controller/Admin/Asset/AssetController.php#L1169-L1183
Proposed fix
} elseif ($request->get('origin') === 'folderPreview') {
\Pimcore::getContainer()->get('messenger.bus.pimcore-core')->dispatch(
new AssetPreviewImageMessage($image->getId())
);
$response = new BinaryFileResponse(PIMCORE_WEB_ROOT . '/bundles/pimcoreadmin/img/video-loading.gif');
$response->headers->set('Cache-Control', 'no-store, must-revalidate');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', '0');
return $response;
}
Changes:
- Dispatch
AssetPreviewImageMessage : triggers async thumbnail generation (same behavior as treeNode)
- Set
Cache-Control: no-store : prevents the browser from caching the placeholder spinner, so the next request hits the server and gets the real thumbnail
Version
2.3.2 (also affects 2.2.x, 2.3.0, 2.3.1)
Description
When uploading images to an asset folder and viewing them in the Preview tab, thumbnails that haven't been generated yet show a loading spinner (
video-loading.gif) that never resolves, even after the thumbnail has been generated by the messenger worker. The spinner persists until the user does a hard browser refresh (Ctrl+F5) or switches to the List view.Root Cause
Two issues in
AssetController::getImageThumbnailAction()at line 1179-1181:1. Placeholder response is cacheable
When
origin=folderPreviewand the thumbnail doesn't exist yet, the controller returnsvideo-loading.gifas aBinaryFileResponsewithoutCache-Control: no-storeheaders. The browser caches this response.The
getFolderContentPreviewActiongenerates thumbnail URLs using the asset'smodificationDateas the_dccache-buster parameter (e.g._dc=1774887063). Since this timestamp never changes for the same asset, subsequent requests hit the browser cache and serve the cached spinner forever.2. No async thumbnail generation is dispatched
For
origin=treeNode, the controller dispatchesAssetPreviewImageMessageto trigger async thumbnail generation. But fororigin=folderPreview, no message is dispatched — the thumbnail is only generated if/when thepimcore_asset_updateworker processes it independently.Steps to Reproduce
Why List view works
The List view uses a different URL pattern:
The Preview (folder) view uses:
Different URL = no cached stale response in the browser.
Current code
https://github.com/pimcore/admin-ui-classic-bundle/blob/2.3/src/Controller/Admin/Asset/AssetController.php#L1169-L1183
Proposed fix
Changes:
AssetPreviewImageMessage: triggers async thumbnail generation (same behavior astreeNode)Cache-Control: no-store: prevents the browser from caching the placeholder spinner, so the next request hits the server and gets the real thumbnail