RocketChat/Rocket.Chat · error · Meteor.Error

could-not-access-webdav

could-not-access-webdav

Error message

Could not access webdav

What it means

A catch-all wrapper around the WebDAV account-creation flow: any failure inside the try block — client.stat('/'), WebdavAccounts.updateOne/insertOne, or api.broadcast — is re-thrown as 'could-not-access-webdav' with the original error discarded. In practice it almost always means the server could not reach or authenticate against the WebDAV endpoint at serverURL. Because the underlying cause is swallowed, you must infer it from the serverURL, token/credentials, and network reachability.

Source

Thrown at apps/meteor/server/bridges/webdav/methods/addWebdavAccount.ts:72

		await WebdavAccounts.updateOne(
			{
				userId,
				serverURL: data.serverURL,
				name: data.name ?? '',
			},
			{
				$set: accountData,
			},
			{
				upsert: true,
			},
		);
		void api.broadcast('notify.webdav', userId, {
			type: 'changed',
			account: accountData,
		});
	} catch (error) {
		throw new Meteor.Error('could-not-access-webdav', 'Could not access webdav', {
			method: 'addWebdavAccount',
		});
	}

	return true;
};

Meteor.methods<ServerMethods>({
	async addWebdavAccount(formData) {
		const userId = Meteor.userId();

		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid User', { method: 'addWebdavAccount' });
		}

		if (!settings.get('Webdav_Integration_Enabled')) {
			throw new Meteor.Error('error-not-allowed', 'WebDAV Integration Not Allowed', {
				method: 'addWebdavAccount',

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify serverURL is reachable and is a WebDAV endpoint from the Rocket.Chat host: curl -X PROPFIND -H 'Depth: 0' <serverURL> with the same credentials/token the account uses.
  2. Confirm the auth mechanism matches: for addWebdavAccountByToken the access_token must be accepted by the server at serverURL; for addWebdavAccount the username/password must be valid Basic-auth credentials.
  3. If using HTTPS with a private/self-signed cert, ensure the CA is trusted by the server process (NODE_EXTRA_CA_CERTS or system trust store); a TLS rejection surfaces here as the same swallowed error.
  4. Temporarily instrument the catch block (or wrap the method in dev) to log the real error object — the production code drops it, which is the main reason this error is hard to diagnose.
  5. If the WebDAV server is upstream/cloud (Nextcloud, ownCloud, etc.), check its admin/logs for the rejected request and confirm the token scope includes WebDAV access.
  6. Rule out a DB-side failure: confirm WebdavAccounts collection is writable and MongoDB is up before assuming a network problem.

Example fix

// before (apps/meteor/server/bridges/webdav/methods/addWebdavAccount.ts:71)
} catch (error) {
  throw new Meteor.Error('could-not-access-webdav', 'Could not access webdav', {
    method: 'addWebdavAccount',
  });
}

// after: preserve the cause for diagnosis while keeping the stable error code
} catch (error) {
  throw new Meteor.Error('could-not-access-webdav', 'Could not access webdav', {
    method: 'addWebdavAccount',
    cause: error,
  });
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: probe the WebDAV endpoint before calling the method, so most
// failure modes surface as a clear message instead of 'could-not-access-webdav'.
async function canReachWebdav(serverURL: string, headers: Record<string, string>): Promise<boolean> {
  try {
    const res = await fetch(serverURL, { method: 'PROPFIND', headers: { ...headers, Depth: '0' } });
    return res.status >= 200 && res.status < 300 || res.status === 207;
  } catch {
    return false;
  }
}

const ok = await canReachWebdav(payload.serverURL, payload.token ? { Authorization: `Bearer ${payload.token.access_token}` } : { Authorization: `Basic ${btoa(`${payload.username}:${payload.password}`)}` });
if (!ok) {
  throw new Error('WebDAV endpoint unreachable or credentials rejected — check URL and auth.');
}

Try / catch

// Catch the stable code; remember the original cause is swallowed server-side,
// so branch the user-facing message on what the client can still verify.
try {
  await Meteor.callAsync('addWebdavAccountByToken', payload);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'could-not-access-webdav') {
    reportToUser('Could not reach the WebDAV server. Verify the URL, credentials/token, and that the server is reachable from this workspace.');
    logToServer('webdav add failed', { serverURL: payload.serverURL, hasToken: !!payload.token });
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Thrown when new WebdavClientAdapter(serverURL, {token}|{username,password}).stat('/') rejects — e.g. wrong/typo URL, DNS failure, TCP refused, TLS/cert error, HTTP 401/403 from the WebDAV server, expired OAuth access_token with no valid refresh_token, or the endpoint is not actually a WebDAV server. Also thrown if WebdavAccounts.updateOne/insertOne or api.broadcast throws (MongoDB down, connection issue), though that is far less common.

Common situations: User mistyped the serverURL or used http:// against an HTTPS-only server; OAuth token expired or refresh_token was never stored; self-signed or corporate-proxy TLS cert the Node process does not trust; WebDAV server behind a VPN the Rocket.Chat host cannot reach; credentials work in a browser but fail because the server expects Basic auth and the client sent Bearer (or vice-versa); rare case of MongoDB connectivity loss during the upsert/insert.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/4f21d14092747ad7. Report an issue: GitHub.