toeverything/AFFiNE · error · GraphqlBadRequest

caldav_insecure_url

caldav_insecure_url

Error message

CalDAV URL must use https.

What it means

After URL parsing succeeds, the CalDAV provider enforces transport security: any protocol other than https: throws GraphqlBadRequest with code caldav_insecure_url, unless the deployment explicitly enables allowInsecureHttp and the URL is plain http. This keeps calendar credentials and data off plaintext transports.

Source

Thrown at packages/backend/server/src/plugins/calendar/providers/caldav.ts:573

    }
  }

  private async assertAllowedUrl(urlValue: string) {
    let url: URL;
    try {
      url = new URL(urlValue);
    } catch {
      throw new GraphqlBadRequest({
        code: 'caldav_invalid_url',
        message: 'CalDAV URL is invalid.',
      });
    }

    if (
      url.protocol !== 'https:' &&
      !(url.protocol === 'http:' && this.allowInsecureHttp)
    ) {
      throw new GraphqlBadRequest({
        code: 'caldav_insecure_url',
        message: 'CalDAV URL must use https.',
      });
    }

    const hostname = url.hostname.toLowerCase();
    if (
      this.allowedHosts.length &&
      !isAllowedHost(hostname, this.allowedHosts)
    ) {
      throw new GraphqlBadRequest({
        code: 'caldav_host_blocked',
        message: 'CalDAV host is not allowed.',
      });
    }
  }

  private toGraphqlSsrfError(error: unknown) {

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Use an https:// CalDAV endpoint — put the server behind TLS.
  2. For local development only, enable the calendar CalDAV allowInsecureHttp option in server config; never enable it in production.
  3. Check the URL for a missing 's' in the scheme.

Example fix

// before
await caldav.connect('http://caldav.local/user'); // blocked when allowInsecureHttp is false

// after
await caldav.connect('https://caldav.example.com/user');
// or, dev-only: set calendar.caldav.allowInsecureHttp = true in server config
Defensive patterns

Strategy: validation

Validate before calling

const allowInsecure = config.calendar.caldav.allowInsecureHttp === true;
function isAllowedScheme(url: string): boolean {
  const proto = new URL(url).protocol;
  return proto === 'https:' || (proto === 'http:' && allowInsecure);
}
if (!isAllowedScheme(caldavUrl)) {
  // prompt for an https:// URL before calling the API
}

Type guard

function isHttpsUrl(v: string): v is `https://${string}` {
  try { return new URL(v).protocol === 'https:'; } catch { return false; }
}

Try / catch

try { await caldav.connect(url); } catch (e) { if (e.code === 'caldav_insecure_url') suggestHttpsUrl(); else throw e; }

Prevention

When it happens

Trigger: Submitting a http:// CalDAV URL on a server where the CalDAV allowInsecureHttp option is false (the default), or a non-https/non-http scheme such as ftp://.

Common situations: Self-hosted CalDAV servers without TLS; local development instances; typo of http:// where https:// was intended; enabling http in dev but forgetting the production flag difference.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/e758b4feadf6a8de. Report an issue: GitHub.