nextcloud/server · error · Sabre\DAV\Exception
$e->getMessage()
Error message
$e->getMessage()
What it means
This is the catch-all branch of OCA\DAV\Connector\Sabre\File::convertToSabreException() (apps/dav/lib/Connector/Sabre/File.php:645). Every exception raised while writing a file through the DAV connector (PUT, chunked upload, MOVE-overwrite) is passed here and mapped to a Sabre DAV exception; anything that is not NotPermitted, Forbidden, EntityTooLarge, InvalidContent, InvalidPath, Locked, GenericEncryption, StorageNotAvailable, NotFound or NotEnoughSpace falls through to a bare \Sabre\DAV\Exception carrying the original message. Since \Sabre\DAV\Exception maps to HTTP 500, this error always means an unmapped, unexpected server-side failure during a file write.
Source
Thrown at apps/dav/lib/Connector/Sabre/File.php:645
if ($e instanceof LockedException || $e instanceof LockNotAcquiredException) {
// the file is currently being written to by another process
throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
if ($e instanceof GenericEncryptionException) {
// returning 503 will allow retry of the operation at a later point in time
throw new ServiceUnavailable($this->l10n->t('Encryption not ready: %1$s', [$e->getMessage()]), 0, $e);
}
if ($e instanceof StorageNotAvailableException) {
throw new ServiceUnavailable($this->l10n->t('Failed to write file contents: %1$s', [$e->getMessage()]), 0, $e);
}
if ($e instanceof NotFoundException) {
throw new NotFound($this->l10n->t('File not found: %1$s', [$e->getMessage()]), 0, $e);
}
if ($e instanceof NotEnoughSpaceException) {
throw new EntityTooLarge($this->l10n->t('Insufficient space'), 0, $e);
}
throw new \Sabre\DAV\Exception($e->getMessage(), 0, $e);
}
/**
* Get the checksum for this file
*
* @return string|null
*/
public function getChecksum() {
return $this->info->getChecksum();
}
public function setChecksum(string $checksum) {
$this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);
$this->refreshInfo();
}
protected function header($string) {
if (!\OC::$CLI) {View on GitHub (pinned to ecdeb153ff)
Solutions
- Check the Nextcloud log (data/nextcloud.log or admin Settings > Log): the wrapped exception is chained as $e->getPrevious(), and its class name and stack trace identify the real failing component.
- If the previous exception comes from a custom storage backend or app, fix or update that app/backend so it throws the documented OCP\Files\* exceptions (StorageNotAvailableException, NotFoundException, ...) which are mapped to proper HTTP codes.
- If you maintain server code, add a mapping branch in convertToSabreException() for the recurring exception type instead of letting it fall through to a 500.
- If the underlying error is a DB/outage problem, resolve the outage and retry the upload; clients should treat HTTP 500 on PUT as retryable with backoff.
Example fix
// before (custom storage throws \MyVendor\S3SdkException during put())
// -> surfaces as: \Sabre\DAV\Exception("cURL error 28 ...") -> HTTP 500
// after (in the custom storage, translate to a mapped exception)
try {
$this->s3Client->putObject($params);
} catch (\MyVendor\S3SdkException $e) {
throw new \OCP\Files\StorageNotAvailableException($e->getMessage(), 0, $e);
// now converts to 503 ServiceUnavailable so clients retry instead of failing hard
} Defensive patterns
Strategy: try-catch
Try / catch
try {
$file->put($stream); // or writeFileHandle
} catch (\Sabre\DAV\Exception $e) {
$cause = $e->getPrevious();
if ($cause instanceof \OCP\Files\StorageNotAvailableException) {
// retry later / surface 503 semantics
}
\OC::$server->getLogger()->error('DAV write failed: ' . get_class($cause), ['exception' => $e]);
throw $e;
} Prevention
- Log the chained previous exception — the outer message alone never identifies the component.
- Storage backends should throw the OCP\Files\* exception types so they map to correct HTTP codes instead of 500.
- Clients should retry HTTP 500 on PUT with backoff only a limited number of times.
- Keep apps that hook into file writes compatible with the current server version.
When it happens
Trigger: A WebDAV PUT (or chunked-upload MOVE/assemble) where the underlying OC\Files storage or an app hook throws an exception type not listed in convertToSabreException(): e.g. a custom storage backend throwing a domain-specific exception, a post-write hook (OC\Files\hook or an Event) throwing, or a database error surfacing as \OCP\DbException or \Doctrine\DBALException during cache update.
Common situations: Third-party external-storage drivers that throw their own exception classes instead of OCP\Files exceptions; encryption or antivirus app hooks failing mid-write; transient database failures; running apps that are incompatible with the server version and throw inside filesystem hooks; object-store (S3/Swift) SDK exceptions leaking through.
Related errors
- Invalid actor "$actorType"
- Too many calendars created
- Calendar limit reached
- Read-only sharees cannot permanently delete trashbin entries
- Permission denied to create a directory in the trashbin
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/e4d0a2b29d31cbd7.
Report an issue: GitHub.