nextcloud / nextcloud/previewgenerator

Cleaning generated previews doesn't clean up database entries.

Open
#670 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
PHP
Stars
520
Forks
55
PR merge metrics
No merged PRs in 30d

Description

How to use GitHub
  • Please use the 👍 reaction to show that you are affected by the same issue.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

I recently cleared my previews because I migrated from a physical instance of nextcloud to a docker instance. Cleaning previews and re-generating made more sense since it reduced the amount of files to transfer and reduce issues in differences in versions.

Steps to reproduce
  1. Generate previews
  2. Clean previews
  3. Attempt to navigate photo to generate a new preview

Because the database still contains an entry for the file I'm trying to view, but the generated preview does not, next cloud throws a stack trace and returns back an error image for the file we are attempting to view the preview of.

I'm testing a manual workaround right now

Expected behaviour

The database shouldn't contain any entries and there should be no previews for the file in the file system, so the preview is generated. If there is a database entry, but the file doesn't exist, the preview should be re-generated and the database entry updated.

Actual behaviour

GUI returns a 500 and the log reports back an error

{"reqId":"jCnAtSZx0A1THfR2XCAM","level":3,"time":"2026-07-27T16:12:52+00:00","remoteAddr":"192.168.50.1","user":"Russell.Weber","app":"index","method":"GET","url":"/apps/photos/api/v1/preview/4258526?etag=d916a3ed5528e0c7695663c41716bbdd&x=1024&y=1024","scriptName":"/index.php","message":"Unable to open preview stream at /var/www/html/data/appdata_ocrlqm104gs0/preview/e/1/7/3/9/e/7/4258526/683-1024.jpg","userAgent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:152.0) Gecko/20100101 Firefox/152.0","version":"34.0.2.1","exception":{"Exception":"OCP\\Files\\NotFoundException","Message":"Unable to open preview stream at /var/www/html/data/appdata_ocrlqm104gs0/preview/e/1/7/3/9/e/7/4258526/683-1024.jpg","Code":0,"Trace":[{"file":"/var/www/html/lib/private/Preview/Storage/StorageFactory.php","line":33,"function":"readPreview","class":"OC\\Preview\\Storage\\LocalPreviewStorage","type":"->","args":[{"__class__":"OC\\Preview\\Db\\Preview","id":"64675969711423489"}]},{"file":"/var/www/html/lib/private/Preview/Storage/PreviewFile.php","line":74,"function":"readPreview","class":"OC\\Preview\\Storage\\StorageFactory","type":"->","args":[{"__class__":"OC\\Preview\\Db\\Preview","id":"64675969711423489"}]},{"file":"/var/www/html/lib/public/AppFramework/Http/FileDisplayResponse.php","line":53,"function":"read","class":"OC\\Preview\\Storage\\PreviewFile","type":"->","args":[]},{"file":"/var/www/html/lib/private/AppFramework/App.php","line":194,"function":"callback","class":"OCP\\AppFramework\\Http\\FileDisplayResponse","type":"->","args":[{"__class__":"OC\\AppFramework\\Http\\Output"}]},{"file":"/var/www/html/lib/private/Route/Router.php","line":324,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OCA\\Photos\\Controller\\PreviewController","index",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"photos.preview.index","fileId":"4258526"}]},{"file":"/var/www/html/lib/base.php","line":1172,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/apps/photos/api/v1/preview/4258526"]},{"file":"/var/www/html/index.php","line":25,"function":"handleRequest","class":"OC","type":"::","args":[]}],"File":"/var/www/html/lib/private/Preview/Storage/LocalPreviewStorage.php","Line":60,"message":"Unable to open preview stream at /var/www/html/data/appdata_ocrlqm104gs0/preview/e/1/7/3/9/e/7/4258526/683-1024.jpg","exception":"{\"class\":\"OCP\\Files\\NotFoundException\",\"message\":\"Unable to open preview stream at /var/www/html/data/appdata_ocrlqm104gs0/preview/e/1/7/3/9/e/7/4258526/683-1024.jpg\",\"code\":0,\"file\":\"/var/www/html/lib/private/Preview/Storage/LocalPreviewStorage.php:60\",\"trace\":\"#0 /var/www/html/lib/private/Preview/Storage/StorageFactory.php(33): OC\\Preview\\Storage\\LocalPreviewStorage->readPreview(Object(OC\\Preview\\Db\\Preview))\\n#1 /var/www/html/lib/private/Preview/Storage/PreviewFile.php(74): OC\\Preview\\Storage\\StorageFactory->readPreview(Object(OC\\Preview\\Db\\Preview))\\n#2 /var/www/html/lib/public/AppFramework/Http/FileDisplayResponse.php(53): OC\\Preview\\Storage\\PreviewFile->read()\\n#3 /var/www/html/lib/private/AppFramework/App.php(194): OCP\\AppFramework\\Http\\FileDisplayResponse->callback(Object(OC\\AppFramework\\Http\\Output))\\n#4 /var/www/html/lib/private/Route/Router.php(324): OC\\AppFramework\\App::main('OCA\\\\Photos\\\\Cont...', 'index', Object(OC\\AppFramework\\DependencyInjection\\DIContainer), Array)\\n#5 /var/www/html/lib/base.php(1172): OC\\Route\\Router->match('/apps/photos/ap...')\\n#6 /var/www/html/index.php(25): OC::handleRequest()\\n#7 {main}\"}","CustomMessage":"Unable to open preview stream at /var/www/html/data/appdata_ocrlqm104gs0/preview/e/1/7/3/9/e/7/4258526/683-1024.jpg"}}
{"reqId":"jCnAtSZx0A1THfR2XCAM","level":2,"time":"2026-07-27T16:12:52+00:00","remoteAddr":"192.168.50.1","user":"Russell.Weber","app":"PHP","method":"GET","url":"/apps/photos/api/v1/preview/4258526?etag=d916a3ed5528e0c7695663c41716bbdd&x=1024&y=1024","scriptName":"/index.php","message":"http_response_code(): Calling http_response_code() after header('HTTP/...') has no effect at /var/www/html/lib/private/Template/TemplateManager.php#118","userAgent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:152.0) Gecko/20100101 Firefox/152.0","version":"34.0.2.1","data":{"app":"PHP"}}

However, even after cleaning the preview, there are entries for this file in the database.

        id         | file_id | storage_id | old_file_id | location_id | width | height | mimetype_id | source_mimetype_id | max | cropped | encrypted |                   etag                   |   mtime    |  size  | version_id 
-------------------+---------+------------+-------------+-------------+-------+--------+-------------+--------------------+-----+---------+-----------+------------------------------------------+------------+--------+------------
 64675966586667009 | 4258526 |          9 |             |             |  2730 |   4096 |          15 |                 15 | t   | f       | f         | d916a3ed5528e0c7695663c41716bbdd         | 1774335346 | 970645 |         -1
 64675969711423489 | 4258526 |          9 |             |             |   683 |   1024 |          15 |                 15 | f   | f       | f         | d916a3ed5528e0c7695663c41716bbdd         | 1774335347 |  89540 |         -1
(2 rows)

Server configuration

Web server: Apache

Database: PostgreSQL

PHP version: 8.5.8

Nextcloud version: 34.0.2

List of activated apps
root@dungeon[~]# ./occ app:list -vvv       
Enabled:
  - activity: 7.0.0
  - admin_audit: 1.24.0
  - app_api: 34.0.0
  - appstore: 1.0.0
  - bruteforcesettings: 7.0.0
  - circles: 34.0.0
  - cloud_federation_api: 1.18.0
  - comments: 1.24.0
  - contactsinteraction: 1.15.0
  - dashboard: 7.14.0
  - dav: 1.39.0
  - duplicatefinder: 1.8.1
  - federatedfilesharing: 1.24.0
  - federation: 1.24.0
  - files: 2.6.0
  - files_downloadlimit: 5.2.0
  - files_external: 1.26.0
  - files_lock: 34.0.1
  - files_pdfviewer: 7.0.0-dev.0
  - files_reminders: 1.7.0
  - files_sharing: 1.26.0
  - files_trashbin: 1.24.0
  - files_versions: 1.27.0
  - firstrunwizard: 7.0.0-dev.0
  - groupfolders: 22.0.5
  - logreader: 7.0.0
  - lookup_server_connector: 1.22.0
  - nextcloud_announcements: 6.0.0
  - notifications: 7.0.0-dev.1
  - oauth2: 1.22.0
  - office: 1.0.0
  - onlyoffice: 10.1.2
  - password_policy: 6.0.0-dev.0
  - photos: 7.0.0
  - previewgenerator: 5.14.0
  - privacy: 6.0.0-dev.1
  - profile: 1.3.0
  - provisioning_api: 1.24.0
  - recognize: 12.0.0
  - recommendations: 7.0.0
  - related_resources: 5.0.0-dev.0
  - serverinfo: 6.0.0
  - settings: 1.17.0
  - sharebymail: 1.24.0
  - support: 6.0.0
  - survey_client: 6.0.0-dev.0
  - systemtags: 1.24.0
  - text: 8.0.0
  - theming: 2.9.0
  - twofactor_backupcodes: 1.23.0
  - twofactor_totp: 16.0.0
  - updatenotification: 1.24.0
  - user_status: 1.14.0
  - viewer: 7.0.0-dev.0
  - weather_status: 1.14.0
  - webhook_listeners: 1.6.0
  - whiteboard: 1.5.9
  - workflowengine: 2.16.0
Disabled:
  - encryption: 2.22.0 (installed 2.20.0)
  - groupquota: 0.2.5 (installed 0.2.5)
  - suspicious_login: 12.0.0-dev.0
  - twofactor_nextcloud_notification: 8.0.0
  - user_ldap: 1.25.0 (installed 1.23.0)

Nextcloud configuration
root@dungeon[~]# ./occ config:list system
{
    "system": {
        "htaccess.RewriteBase": "\/",
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "password": "***REMOVED SENSITIVE VALUE***",
            "port": 6379
        },
        "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
        "upgrade.disable-web": true,
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "pgsql",
        "version": "34.0.2.1",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "serverid": "ocrlqm104gs1",
        "preview_max_memory": -1,
        "loglevel": 2,
        "maintenance": false,
        "data-fingerprint": "f6de0f345fac337c7fafd2a65bd245a5",
        "overwritehost": "cloud.weberbia.ninja",
        "overwriteprotocol": "https",
        "overwrite.cli.url": "https:\/\/cloud.weberbia.ninja",
        "default_phone_region": "US",
        "maintenance_window_start": 1,
        "mail_smtpmode": "smtp",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_sendmailmode": "smtp",
        "mail_smtpport": "587",
        "mail_smtpauth": true,
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "preview_imaginary_url": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "127.0.0.1",
            "192.168.50.2",
            "cloud.weberbia.ninja",
            "dungeon.weberbia.ninja",
            "dungeon.weberbia.ninja:3000",
            "localhost",
            "nextcloud",
            "nextcloud.weberbia.ninja",
            "nginx"
        ]
    }
}

Browser

Browser name: ALL
Browser version: ALL
Operating system: Ubuntu

Browser log
500:  the image "https://<IMAGEURI>x=1024y=1024" cannot be displayed because it contains errors.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the Photos preview request through lib/private/Preview/Storage/StorageFactory.php and lib/private/Preview/Storage/LocalPreviewStorage.php, using the reported missing preview path and database rows as the reproduction. Check how cleaning previews and subsequent preview generation handle stale entries; done means an absent preview is regenerated without a 500 error or a database record pointing to a missing file.

Written by the indexing model from the issue text.

Assessment

Tech stack
php, postgresql
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.