{"record":{"id":"29cb5487a3ee9863","repo":"nextcloud/server","slug":"storage-is-invalid","errorCode":null,"errorMessage":"Storage {} is invalid","messagePattern":"Storage (.+?) is invalid","errorType":"exception","errorClass":"Sabre\\DAV\\Exception\\NotFound","httpStatus":404,"severity":"error","filePath":"apps/dav/lib/Connector/Sabre/ObjectTree.php","lineNumber":116,"sourceCode":"\t\t\t\t */\n\t\t\t\t// get data directly\n\t\t\t\t$data = $storage->getMetaData($internalPath);\n\t\t\t\t$info = new FileInfo($absPath, $storage, $internalPath, $data, $mount);\n\t\t\t} else {\n\t\t\t\t$info = null;\n\t\t\t}\n\t\t} else {\n\t\t\t// read from cache\n\t\t\ttry {\n\t\t\t\t$info = $this->fileView->getFileInfo($path);\n\n\t\t\t\tif ($info instanceof \\OCP\\Files\\FileInfo && $info->getStorage()->instanceOfStorage(FailedStorage::class)) {\n\t\t\t\t\tthrow new StorageNotAvailableException();\n\t\t\t\t}\n\t\t\t} catch (StorageNotAvailableException $e) {\n\t\t\t\tthrow new \\Sabre\\DAV\\Exception\\ServiceUnavailable('Storage is temporarily not available', 0, $e);\n\t\t\t} catch (StorageInvalidException $e) {\n\t\t\t\tthrow new \\Sabre\\DAV\\Exception\\NotFound('Storage ' . $path . ' is invalid');\n\t\t\t} catch (LockedException $e) {\n\t\t\t\tthrow new \\Sabre\\DAV\\Exception\\Locked();\n\t\t\t} catch (ForbiddenException $e) {\n\t\t\t\tthrow new \\Sabre\\DAV\\Exception\\Forbidden();\n\t\t\t}\n\t\t}\n\n\t\tif (!$info) {\n\t\t\tthrow new \\Sabre\\DAV\\Exception\\NotFound('File with name ' . $path . ' could not be located');\n\t\t}\n\n\t\tif ($info->getType() === 'dir') {\n\t\t\t$node = new Directory($this->fileView, $info, $this);\n\t\t} else {\n\t\t\t$node = new File($this->fileView, $info);\n\t\t}\n\n\t\t$this->cache[$path] = $node;","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/Connector/Sabre/ObjectTree.php#L98-L134","documentation":"Thrown by ObjectTree::getNodeForPath() (apps/dav/lib/Connector/Sabre/ObjectTree.php:116) as \\Sabre\\DAV\\Exception\\NotFound (HTTP 404) when getFileInfo() throws \\OCP\\Files\\StorageInvalidException. Unlike StorageNotAvailableException, this signals the storage itself is invalid — not temporarily down — so the server answers 404 with 'Storage <path> is invalid': the mount cannot be used at all in its current state.","triggerScenarios":"WebDAV access to a path whose storage reported itself invalid — e.g. a local storage whose root directory was deleted, or an external storage configuration that resolves to an unusable backend; typically triggered during getFileInfo() when the mount's storage id no longer matches a loadable storage.","commonSituations":"data directory or a mounted external root deleted/moved on disk while Nextcloud still has cache entries; external storage definitions corrupted after restoring a backup or database migration without the matching storage config; id mismatches between filecache storages and mounts after manual DB surgery.","solutions":["Inspect nextcloud.log for the chained StorageInvalidException and identify which storage/mount the path belongs to (occ files_external:list).","Restore the storage's root (recreate the deleted directory, or re-save the external mount so it gets a valid configuration).","If the mount is permanently gone, remove it cleanly via Settings > External storage or occ files_external:delete <id>, then occ files:scan --user <uid> to reconcile the cache.","Verify datadirectory/permissions in config.php if the invalid storage is the primary local root."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $node = $server->tree->getNodeForPath($path);\n} catch (\\Sabre\\DAV\\Exception\\NotFound $e) {\n    if (str_contains($e->getMessage(), 'is invalid')) {\n        // storage marked invalid: administrative repair needed, not a plain missing file\n        $this->adminAlert->raise('Invalid storage for path ' . $path);\n    } else {\n        // genuine 404 handling\n    }\n}","preventionTips":["Do not delete or move data directories or external mount roots behind Nextcloud's back.","After restoring from backup, run occ files:scan --all to reconcile storages and cache.","Remove decommissioned external mounts via occ files_external:delete, not by editing the DB directly."],"tags":["dav","storage","invalid-storage","not-found","files-external"],"backgroundTag":"invalid-storage-configuration","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}