strapi/strapi · error · ProviderValidationError

Invalid protocol "${url.protocol}"

Error message

Invalid protocol "${url.protocol}"

What it means

Thrown by bootstrap() in the remote destination provider if options.url.protocol is not 'http:' or 'https:'. The provider derives the WebSocket protocol from this (wss: from https:, ws: from http:), so only HTTP(S) URLs are valid. It is a ProviderValidationError with check: 'url'.

Source

Thrown at packages/core/data-transfer/src/strapi/providers/remote-destination/index.ts:351

    this.#diagnostics?.report({
      details: {
        createdAt: new Date(),
        message,
        origin: 'remote-destination-provider',
      },
      kind: 'warning',
    });
  }

  async bootstrap(diagnostics?: IDiagnosticReporter): Promise<void> {
    this.#diagnostics = diagnostics;
    const { url, auth } = this.options;
    const validProtocols = ['https:', 'http:'];

    let ws: WebSocket;

    if (!validProtocols.includes(url.protocol)) {
      throw new ProviderValidationError(`Invalid protocol "${url.protocol}"`, {
        check: 'url',
        details: {
          protocol: url.protocol,
          validProtocols,
        },
      });
    }
    const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
    const wsUrl = `${wsProtocol}//${url.host}${trimTrailingSlash(
      url.pathname
    )}${TRANSFER_PATH}/push`;

    this.#reportInfo('establishing websocket connection');
    // No auth defined, trying public access for transfer
    if (!auth) {
      ws = await connectToWebsocket(wsUrl, undefined, this.#diagnostics);
    }

View on GitHub (pinned to 4a4101264d)

Solutions

  1. Ensure the URL includes the http:// or https:// scheme (e.g., new URL('https://remote-strapi.example.com')).
  2. Do not pass ws:// or wss:// — the provider converts http→ws and https→wss automatically.
  3. Validate the URL protocol before constructing the provider.

Example fix

// before
const provider = createRemoteStrapiDestinationProvider({
  url: new URL('wss://remote-strapi.example.com'), // wrong protocol
  strategy: 'restore',
});
// after
const provider = createRemoteStrapiDestinationProvider({
  url: new URL('https://remote-strapi.example.com'),
  strategy: 'restore',
});
Defensive patterns

Strategy: validation

Validate before calling

function validateTransferUrl(url: URL): void {
  const validProtocols = ['https:', 'http:'];
  if (!validProtocols.includes(url.protocol)) {
    throw new Error(
      `URL protocol must be http: or https: (got "${url.protocol}"). Do not use ws:/wss:.`
    );
  }
}

const url = new URL(rawUrlString);
validateTransferUrl(url);

Type guard

function isHttpUrl(url: URL): boolean {
  return url.protocol === 'http:' || url.protocol === 'https:';
}

Try / catch

try {
  await provider.bootstrap();
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Invalid protocol')) {
    console.error('Use http:// or https:// in the transfer URL.');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Passing a URL with protocol 'ftp:', 'file:', 'ws:', 'wss:', or an empty protocol. Passing a string that was not parsed into a URL object with a protocol. Constructing a URL without a scheme (e.g., new URL('remote-strapi.example.com')).

Common situations: User enters a URL without the https:// prefix in the CLI. A configuration value stored as a bare hostname. Passing a ws:// or wss:// URL directly (the provider expects http/https and derives ws/wss internally).

Related errors


AI-assisted analysis of strapi/strapi@4a4101264d (2026-08-12). Data as JSON: /api/errors/c6606607867cd7f2. Report an issue: GitHub.