"No delete permission for path" error when upgrading from NC 26 to 27

Nextcloud version (eg, 20.0.5): 26.0.2.1 / 27.0.0.8
Operating system and version (eg, Ubuntu 20.04): Docker running on Ubuntu 22.04
Apache or nginx version (eg, Apache 2.4.25): Apache/2.4.56 (Debian)
PHP version (eg, 7.4): PHP 8.2.7 (cli) (built: Jun 14 2023 05:26:32) (NTS)

The issue you are facing:
I tried to upgrade from NC 26.0.2.1 to NC 27.0.0. I’m stuck at the step below. It looks like that there is an issue with deleting a specigfic folder with its content. In general this folder does exist. Permissions are correct:

 6946829 drwxr-xr-x   2 www-data www-data  4096 Jun 16 19:57 7e04f0290d19a57925395ce78ef282a0

Could you please guide me to solve the issue

Is this the first time you’ve seen this error? (Y/N): Y

Steps to replicate it:

  1. login to Docker container
  2. run php occ upgrade

Output:

www-data@nextcloud:~/html$ php occ upgrade
Nextcloud or one of the apps require upgrade - only a limited number of commands are available
You may use your browser or the occ upgrade command to do the upgrade
Setting log level to debug
Updating database schema
Updated database
Updating <dav> ...
Exception: Database error when running migration 1027Date20230504122946 for app dav
No delete permission for path "/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0"
Update failed
Maintenance mode is kept active
Resetting log level

The output of your Nextcloud log in Admin > Logging:

\\OC\\Updater::setDebugLogLevel: Set log level to debug
starting upgrade from 26.0.2.1 to 27.0.0.8
OC\\Repair\\Events\\RepairStepEvent: Repair step: Repair MySQL collation","userAgent":"--","version":"26.0.2.1
OC\\Repair\\Events\\RepairInfoEvent: Repair info: All tables already have the correct collation -> nothing to do
OC\\Repair\\Events\\RepairStepEvent: Repair step: Repair SQLite autoincrement
OC\\Repair\\Events\\RepairStepEvent: Repair step: Copy data from accounts table when migrating from ownCloud
OC\\Repair\\Events\\RepairStepEvent: Repair step: Drop account terms table when migrating from ownCloud
\\OC\\Updater::dbUpgradeBefore: Updating database schema
\\OC\\Updater::dbUpgrade: Updated database
\\OC\\Updater::appUpgradeStarted: Updating <dav> ...
Activity generated for a changed card in addressbook 2
Database error when running migration 1027Date20230504122946 for app dav\nNo delete permission for path \"/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0\

Output errors in nextcloud.log in /var/www/ or as admin user in top right menu, filtering for errors. Use a pastebin service if necessary.

{"reqId":"GYZDIXuXaZB7rh89A3S5","level":3,"time":"2023-06-16T18:08:22+00:00","remoteAddr":"","user":"--","app":"no app in context","method":"","url":"--","message":"Database error when running migration 1027Date20230504122946 for app dav\nNo delete permission for path \"/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0\"","userAgent":"--","version":"26.0.2.1","exception":{"Exception":"Exception","Message":"Database error when running migration 1027Date20230504122946 for app dav\nNo delete permission for path \"/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0\"","Code":0,"Trace":[{"file":"/var/www/html/lib/private/legacy/OC_App.php","line":844,"function":"migrate","class":"OC\\DB\\MigrationService","type":"->","args":[]},{"file":"/var/www/html/lib/private/Updater.php","line":359,"function":"updateApp","class":"OC_App","type":"::","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/Updater.php","line":271,"function":"doAppUpgrade","class":"OC\\Updater","type":"->","args":[]},{"file":"/var/www/html/lib/private/Updater.php","line":139,"function":"doUpgrade","class":"OC\\Updater","type":"->","args":["27.0.0.8","26.0.2.1"]},{"file":"/var/www/html/core/Command/Upgrade.php","line":225,"function":"upgrade","class":"OC\\Updater","type":"->","args":[]},{"file":"/var/www/html/3rdparty/symfony/console/Command/Command.php","line":298,"function":"execute","class":"OC\\Core\\Command\\Upgrade","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/3rdparty/symfony/console/Application.php","line":1040,"function":"run","class":"Symfony\\Component\\Console\\Command\\Command","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/3rdparty/symfony/console/Application.php","line":301,"function":"doRunCommand","class":"Symfony\\Component\\Console\\Application","type":"->","args":[["OC\\Core\\Command\\Upgrade"],["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/3rdparty/symfony/console/Application.php","line":171,"function":"doRun","class":"Symfony\\Component\\Console\\Application","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/lib/private/Console/Application.php","line":211,"function":"run","class":"Symfony\\Component\\Console\\Application","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/console.php","line":100,"function":"run","class":"OC\\Console\\Application","type":"->","args":[]},{"file":"/var/www/html/occ","line":11,"args":["/var/www/html/console.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/DB/MigrationService.php","Line":421,"Previous":{"Exception":"OCP\\Files\\NotPermittedException","Message":"No delete permission for path \"/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0\"","Code":0,"Trace":[{"file":"/var/www/html/lib/private/Files/SimpleFS/SimpleFolder.php","line":67,"function":"delete","class":"OC\\Files\\Node\\Folder","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/CardDAV/PhotoCache.php","line":286,"function":"delete","class":"OC\\Files\\SimpleFS\\SimpleFolder","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/Listener/ClearPhotoCacheListener.php","line":45,"function":"delete","class":"OCA\\DAV\\CardDAV\\PhotoCache","type":"->","args":["*** sensitive parameters replaced ***","*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/EventDispatcher/ServiceEventListener.php","line":86,"function":"handle","class":"OCA\\DAV\\Listener\\ClearPhotoCacheListener","type":"->","args":[["OCA\\DAV\\Events\\CardUpdatedEvent"]]},{"file":"/var/www/html/3rdparty/symfony/event-dispatcher/EventDispatcher.php","line":251,"function":"__invoke","class":"OC\\EventDispatcher\\ServiceEventListener","type":"->","args":[["OCA\\DAV\\Events\\CardUpdatedEvent"],"OCA\\DAV\\Events\\CardUpdatedEvent",["Symfony\\Component\\EventDispatcher\\EventDispatcher"]]},{"file":"/var/www/html/3rdparty/symfony/event-dispatcher/EventDispatcher.php","line":73,"function":"callListeners","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"->","args":[[["Closure"],["Closure"],["Closure"]],"OCA\\DAV\\Events\\CardUpdatedEvent",["OCA\\DAV\\Events\\CardUpdatedEvent"]]},{"file":"/var/www/html/lib/private/EventDispatcher/EventDispatcher.php","line":87,"function":"dispatch","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"->","args":[["OCA\\DAV\\Events\\CardUpdatedEvent"],"OCA\\DAV\\Events\\CardUpdatedEvent"]},{"file":"/var/www/html/lib/private/EventDispatcher/EventDispatcher.php","line":99,"function":"dispatch","class":"OC\\EventDispatcher\\EventDispatcher","type":"->","args":["OCA\\DAV\\Events\\CardUpdatedEvent",["OCA\\DAV\\Events\\CardUpdatedEvent"]]},{"file":"/var/www/html/apps/dav/lib/CardDAV/CardDavBackend.php","line":745,"function":"dispatchTyped","class":"OC\\EventDispatcher\\EventDispatcher","type":"->","args":[["OCA\\DAV\\Events\\CardUpdatedEvent"]]},{"file":"/var/www/html/lib/public/AppFramework/Db/TTransactional.php","line":63,"function":"OCA\\DAV\\CardDAV\\{closure}","class":"OCA\\DAV\\CardDAV\\CardDavBackend","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/apps/dav/lib/CardDAV/CardDavBackend.php","line":718,"function":"atomic","class":"OCA\\DAV\\CardDAV\\CardDavBackend","type":"->","args":[["Closure"],["OC\\DB\\ConnectionAdapter"]]},{"file":"/var/www/html/apps/dav/lib/CardDAV/SyncService.php","line":241,"function":"updateCard","class":"OCA\\DAV\\CardDAV\\CardDavBackend","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/public/AppFramework/Db/TTransactional.php","line":63,"function":"OCA\\DAV\\CardDAV\\{closure}","class":"OCA\\DAV\\CardDAV\\SyncService","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/apps/dav/lib/CardDAV/SyncService.php","line":229,"function":"atomic","class":"OCA\\DAV\\CardDAV\\SyncService","type":"->","args":[["Closure"],["OC\\DB\\ConnectionAdapter"]]},{"file":"/var/www/html/apps/dav/lib/CardDAV/SyncService.php","line":278,"function":"updateUser","class":"OCA\\DAV\\CardDAV\\SyncService","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/User/Manager.php","line":527,"function":"OCA\\DAV\\CardDAV\\{closure}","class":"OCA\\DAV\\CardDAV\\SyncService","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/apps/dav/lib/CardDAV/SyncService.php","line":277,"function":"callForAllUsers","class":"OC\\User\\Manager","type":"->","args":[["Closure"]]},{"file":"/var/www/html/apps/dav/lib/Migration/Version1027Date20230504122946.php","line":52,"function":"syncInstance","class":"OCA\\DAV\\CardDAV\\SyncService","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/DB/MigrationService.php","line":537,"function":"postSchemaChange","class":"OCA\\DAV\\Migration\\Version1027Date20230504122946","type":"->","args":[["OC\\Migration\\SimpleOutput"],["Closure"],["oc_"]]},{"file":"/var/www/html/lib/private/DB/MigrationService.php","line":417,"function":"executeStep","class":"OC\\DB\\MigrationService","type":"->","args":["1027Date20230504122946",false]},{"file":"/var/www/html/lib/private/legacy/OC_App.php","line":844,"function":"migrate","class":"OC\\DB\\MigrationService","type":"->","args":[]},{"file":"/var/www/html/lib/private/Updater.php","line":359,"function":"updateApp","class":"OC_App","type":"::","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/Updater.php","line":271,"function":"doAppUpgrade","class":"OC\\Updater","type":"->","args":[]},{"file":"/var/www/html/lib/private/Updater.php","line":139,"function":"doUpgrade","class":"OC\\Updater","type":"->","args":["27.0.0.8","26.0.2.1"]},{"file":"/var/www/html/core/Command/Upgrade.php","line":225,"function":"upgrade","class":"OC\\Updater","type":"->","args":[]},{"file":"/var/www/html/3rdparty/symfony/console/Command/Command.php","line":298,"function":"execute","class":"OC\\Core\\Command\\Upgrade","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/3rdparty/symfony/console/Application.php","line":1040,"function":"run","class":"Symfony\\Component\\Console\\Command\\Command","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/3rdparty/symfony/console/Application.php","line":301,"function":"doRunCommand","class":"Symfony\\Component\\Console\\Application","type":"->","args":[["OC\\Core\\Command\\Upgrade"],["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/3rdparty/symfony/console/Application.php","line":171,"function":"doRun","class":"Symfony\\Component\\Console\\Application","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/lib/private/Console/Application.php","line":211,"function":"run","class":"Symfony\\Component\\Console\\Application","type":"->","args":[["Symfony\\Component\\Console\\Input\\ArgvInput"],["Symfony\\Component\\Console\\Output\\ConsoleOutput"]]},{"file":"/var/www/html/console.php","line":100,"function":"run","class":"OC\\Console\\Application","type":"->","args":[]},{"file":"/var/www/html/occ","line":11,"args":["/var/www/html/console.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/Files/Node/Folder.php","Line":368},"message":"Database error when running migration 1027Date20230504122946 for app dav\nNo delete permission for path \"/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0\"","exception":{},"CustomMessage":"Database error when running migration 1027Date20230504122946 for app dav\nNo delete permission for path \"/appdata_ociucjesv6n3/dav-photocache/7e04f0290d19a57925395ce78ef282a0\""}}

That’s weird.

Can you try a occ files:scan-app-data?

What’s the underlying volume type in Docker?

And what’s the underlying OS filesystem?

Hi jtr, thanks for your answer. Sorry for the late response but I had to analyze the issue a little bit deeper on my end first before I answer.
The volume is just mounted to the host file system which is ext4. The mount definition is within a composer file like

    volumes:
      - /data/nextcloud_data:/var/www/html/data

However, I was able to fix this issue – though, I’m not sure what’s the consequence of my fix and additionally from that what I have seen in the database it doesn’t make sense.
It looks like that there were duplicate entries for the specific files/folder in table oc_filecache. After deleting one of the duplicates the upgrade then complained about the next folder.

Let me try to explain. There are 2 entries for the same folder/files in oc_filecache:

fileid	storage	 path	 path_hash	parent	 name	mimetype	mimepart	size	mtime	storage_mtime	encrypted	unencrypted_size	 etag	permissions	checksum	 
4926	 1	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 3a5aed802cecfae7384fd5272e01485b	 156	 046575206faf0e38bed4a61f4ec673ff	 2	 1	 22159	 1584607229	 1584607229	 0	 0	 5ccc629448104	 31	 	
4927	 1	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 9b09b882529be334d46f07209eb9cb0d	 4926	 photo.png	 9	 7	 19698	 1556137080	 1556137080	 0	 0	 c392753baecde623c26290a1ee045f11	 27	 	
4928	 1	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 ed9940f53b84186f110422d80f241aef	 4926	 photo.32.png	 9	 7	 500	 1556137080	 1556137080	 0	 0	 0580a0f8f104010f577ad2c50cc5fe10	 27	 	
5063	 1	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 00d5175d87d80d9c95470e28422d151e	 4926	 photo.128.png	 9	 7	 1961	 1556898452	 1556898452	 0	 0	 7c3d883644ffc49252cacf7dd1299629	 27	 	
17046	 1	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 74bf3367c31d4b2c6399d7a487186431	 4926	 photo.64.png	 9	 7	 1039	 1584607229	 1584607229	 0	 0	 de20f6cd5f9509488c8cbab4c49ef502	 27	 	
31444	 14	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 3a5aed802cecfae7384fd5272e01485b	 31277	 046575206faf0e38bed4a61f4ec673ff	 2	 1	 23198	 1611512445	 1611512445	 0	 0	 600dbb937274a	 23	 	
31490	 14	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 00d5175d87d80d9c95470e28422d151e	 31444	 photo.128.png	 9	 7	 1961	 1611512445	 1611512445	 0	 0	 de062521cb13e534967396736d9b70c6	 19	 	
31491	 14	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 ed9940f53b84186f110422d80f241aef	 31444	 photo.32.png	 9	 7	 500	 1611512445	 1611512445	 0	 0	 23a84a66b81a16f010daefd743f6a393	 19	 	
31492	 14	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 9b09b882529be334d46f07209eb9cb0d	 31444	 photo.png	 9	 7	 19698	 1611512445	 1611512445	 0	 0	 eb1c82e16a0e29cab75b00a9a5f220a7	 19	 	
31493	 14	appdata_ociucjesv6n3/dav-photocache/046575206faf0e38bed4a61f4ec673ff	 74bf3367c31d4b2c6399d7a487186431	 31444	 photo.64.png	 9	 7	 1039	 1611512445	 1611512445	 0	 0	 bd4293ef989b376a5e8ef1fbb51b77f0	 19	 	

As you can see, one of the differences is the storage column. I assume this is the foreign key to oc_storages, which contains for id 1 and 14:

 numeric_id 	id 	available 	last_checked 	
1 	local::/data/nextcloud/     1 	NULL
14 	local::/var/www/html/data/ 	1 	NULL 

Entry id 1 is the old path which does not exist anymore. It was used when I ran Nextcloud out of a Docker container. Entry id 14 is the new path within the Docker container, which makes sense.

However, the weird thing is, that the issue got fixed when I deleted the entries from oc_filecache with storage ID 14!
As you can see the storage ID is not the only difference. I assume it has something to do with the permission column. Compared to the entries with storage ID 1, it is different. But I don’t have any clue what is behind that because I cannot find a table with the permission types.

Now I have several questions:

  1. What is the oc_filecache about? I’m asking because by mistake (while testing if I can manually delete a folder within the Docker container from the host system, and yes it worked :wink:), I deleted one of the folders and I don’t have a backup of the dav-photocache folder.
  2. Can I (safely) delete all entries which refer to storage ID 1 and as a consequence, can I delete the storage folder ID 1 from oc_storages then?
  3. What might have caused this issue?
    a. Is it related to the permission column?
    b. Where can I find the permission mapping table?

BTW: when I now check the entry in the table oc_filecache for the same folder name 046575206faf0e38bed4a61f4ec673ff, I can now find duplicate entries, again. But with permission 31/27. Same like storage ID 1.

Can you try a occ files:scan-app-data?
In the meantime I’ve executed your command as well, but this was done after my fix-

www-data@nextcloud:~/html$ ./occ files:scan-app-data
Scanning AppData for files

+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 132260  | 61825 | 00:18:13     |
+---------+-------+--------------+

This might be the reason why I can find new (valid) entiries in the table.