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
- Ensure the request includes a well-formed https:// WebDAV public link URL
- If testing against a local server, enable allowLocalUrls in the Companion webdav provider options (never in production)
- 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
- Send full absolute https URLs for public links
- Enable allowLocalUrls only in local dev
- Validate the URL in the picker UI before submission
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
- invalid destination url
- Invalid URL
- File data is missing for file ${options.file.id}
- Missing S3 object key for aborting upload
- Missing S3 object key for resuming upload
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/1387b9fe06c95c6a.
Report an issue: GitHub.