transloadit/uppy · error · Error

invalid public link url

Error message

invalid public link url

What it means

WebDAV public-link mode (username omitted, only url passed) validates the URL before creating a client. It throws 'invalid public link url' when the url is null/empty or fails validateURL — which enforces protocol and (unless allowLocalUrls) rejects localhost/private addresses for SSRF protection.

Source

Thrown at packages/@uppy/companion/src/server/provider/webdav/index.ts:59

  }: {
    providerUserSession: WebdavUserSession
  }): boolean {
    return providerUserSession.webdavUrl != null
  }

  async getClient({
    providerUserSession,
  }: {
    providerUserSession: WebdavUserSession
  }): Promise<WebdavClient> {
    const webdavUrl = providerUserSession?.webdavUrl
    const { allowLocalUrls } = this
    if (
      webdavUrl == null ||
      webdavUrl.length === 0 ||
      !validateURL(webdavUrl, allowLocalUrls)
    ) {
      throw new Error('invalid public link url')
    }

    // Is this an ownCloud or Nextcloud public link URL? e.g. https://example.com/s/kFy9Lek5sm928xP
    // they have specific urls that we can identify
    // todo not sure if this is the right way to support nextcloud and other webdavs
    if (/\/s\/([^/]+)/.test(webdavUrl)) {
      const [baseURL, publicLinkToken] = webdavUrl.split('/s/')
      if (!baseURL) {
        throw new Error('invalid public link url')
      }

      return this.getClientHelper({
        url: `${baseURL.replace('/index.php', '')}/public.php/webdav/`,
        authType: AuthType.Password,
        username: publicLinkToken!,
        password: 'null',
      })
    }

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure the request includes a well-formed https:// WebDAV public link URL
  2. If testing against a local server, enable allowLocalUrls in the Companion webdav provider options (never in production)
  3. Validate/normalize the URL client-side before sending it to Companion

Example fix

// before
const opts = { provider: 'webdav' } // url missing

// after
const opts = {
  provider: 'webdav',
  url: 'https://cloud.example.com/s/kFy9Lek5sm928xP',
}
// companion config for local testing:
// { providerOptions: { webdav: { allowLocalUrls: true } } }
Defensive patterns

Strategy: validation

Validate before calling

import validateURL from './validateURL.js'
if (webdavUrl == null || webdavUrl.length === 0 || !validateURL(webdavUrl, allowLocalUrls)) {
  // reject client-side before calling Companion
  throw new Error('invalid public link url')
}

Type guard

const isValidPublicLink = (u: string, allowLocal = false): boolean => {
  try { const parsed = new URL(u); return parsed.protocol === 'https:' || (allowLocal && parsed.hostname === 'localhost') } catch { return false }
}

Try / catch

try { await provider.client({ url }) } catch (e) { if (e instanceof Error && e.message === 'invalid public link url') { showUrlError() } throw e }

Prevention

When it happens

Trigger: Calling provider.client()/getClient() in public-link mode with a missing, empty, or malformed url; using a http:// URL when only https is allowed; passing a localhost/127.0.0.1/private-IP URL while allowLocalUrls is false.

Common situations: Frontend not sending the url field when the user picks 'public link auth'; users pasting `http://` or typo'd URLs; testing against a local Nextcloud without allowLocalUrls: true in Companion's webdav provider options.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/1387b9fe06c95c6a. Report an issue: GitHub.