You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
disable scans all of filecache; decrypt-all only walks /$uid/files. They disagree on what "all encrypted files" means.
Bug 2 — misleading success message
DecryptAll::decryptAll() prints all files could be decrypted successfully! whenever no exception bubbled up, even though versions/trashbin/shares were never visited and encrypted rows remain. The admin has no signal that anything was left behind.
Diagnostic for affected admins
SELECTfc.fileid, fc.path, fc.encrypted, s.idAS storage
FROM oc_filecache fc
JOIN oc_storages s ONfc.storage=s.numeric_idWHEREfc.encrypted>=1;
(Adjust the oc_ prefix.) The path column shows the blocking rows — typically files_versions/… / files_trashbin/….
Workaround
occ trashbin:cleanup --all-users
occ versions:cleanup
re-run occ encryption:decrypt-all, then occ encryption:disable
for shared/external leftovers, decrypt per-owner: occ encryption:decrypt-all <uid>
Proposed fix (for discussion)
Make encryption:disablereport the blocking paths instead of a generic message, so the admin knows what is left.
Either have decrypt-all also clear the encrypted flag for versions/trashbin, or scope the disable check to the same paths decrypt-all actually clears.
Stop printing "all files could be decrypted successfully!" when storages/paths were skipped or $this->failed would have applied to untouched namespaces.
Summary
occ encryption:decrypt-allreports success, butocc encryption:disablestill fails with:Root cause is a scope mismatch between the two commands plus a misleading success message.
Reported by an admin on central: https://central.owncloud.org/t/unable-to-disable-encryption/94685 — and closely related to #39212.
Analysis
The disable gate (
core/Command/Encryption/Disable.php) scans the entirefilecachetable:decrypt-all(lib/private/Encryption/DecryptAll.php) only ever clears the flag for files under one root:decryptUsersFiles()seeds the walk from'/' . $uid . '/files'— and nothing else.decryptFile()is the only place that resets the column:$storage->getCache()->put($internalPath, ['encrypted' => 0]).instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')).So any
filecacherow withencrypted >= 1outside/$uid/filessurvives and permanently blocks disable:/$uid/files_versions/*(most common)/$uid/files_trashbin/*.decrypted.<timestamp>.partfiles in Enabled encryption, encrypted all files, corrupted uploads, can't disable encryption, dangling.partfiles everywhere that can't be deleted #39212Bug 1 — scope mismatch
disable scans all of
filecache; decrypt-all only walks/$uid/files. They disagree on what "all encrypted files" means.Bug 2 — misleading success message
DecryptAll::decryptAll()printsall files could be decrypted successfully!whenever no exception bubbled up, even though versions/trashbin/shares were never visited and encrypted rows remain. The admin has no signal that anything was left behind.Diagnostic for affected admins
(Adjust the
oc_prefix.) Thepathcolumn shows the blocking rows — typicallyfiles_versions/…/files_trashbin/….Workaround
occ trashbin:cleanup --all-usersocc versions:cleanupocc encryption:decrypt-all, thenocc encryption:disableocc encryption:decrypt-all <uid>Proposed fix (for discussion)
encryption:disablereport the blocking paths instead of a generic message, so the admin knows what is left.decrypt-allalso clear theencryptedflag for versions/trashbin, or scope the disable check to the same paths decrypt-all actually clears.$this->failedwould have applied to untouched namespaces.🤖 Generated with Claude Code