Budibase/budibase · error · HTTPError
Import url must not contain credentials
Error message
Import url must not contain credentials
What it means
parseImportUrl throws this HTTPError(400) when the URL embeds user credentials (user:pass@host), which Budibase disallows to prevent credential leakage into stored import sources and SSRF-style misuse.
Source
Thrown at packages/server/src/api/controllers/query/import/index.ts:87
crypto.createHash("sha512").update(JSON.stringify(input)).digest("hex")
const buildCacheKey = (input: ImporterInput) =>
`openapiSpecs:${stringToHashKey(JSON.stringify("data" in input ? input.data : input.url))}`
function parseImportUrl(url: string): URL {
let parsed: URL
try {
parsed = new URL(url)
} catch {
throw new HTTPError("Invalid import url", 400)
}
if (!ALLOWED_IMPORT_PROTOCOLS.has(parsed.protocol)) {
throw new HTTPError("Only HTTP(S) URLs are allowed for query import", 400)
}
if (parsed.username || parsed.password) {
throw new HTTPError("Import url must not contain credentials", 400)
}
return parsed
}
async function fetchFromUrl(url: string): Promise<string> {
try {
// validate protocol / credentials up front for clear 400 errors
parseImportUrl(url)
// fetchWithBlacklist resolves and validates the target, pins the request to
// the validated IP (preventing DNS rebinding between validation and the
// actual connection) and safely follows redirects, re-validating each hop.
const response = await utils.fetchWithBlacklist(url)
if (!response.ok) {
throw new HTTPError(
`Failed to fetch import data (status ${response.status})`,
response.statusView on GitHub (pinned to a81a902e9a)
Solutions
- Remove the username/password from the URL and use headers for authentication instead
- Use API-key headers or a proxy that injects credentials server-side
- Configure the datasource auth separately from the import URL
Example fix
// before const url = 'https://admin:s3cret@api.example.com/data.json' // after const url = 'https://api.example.com/data.json' // pass auth via headers
Defensive patterns
Strategy: validation
Validate before calling
const u = new URL(url)
if (u.username || u.password) throw new Error('Remove credentials from the URL; supply auth via headers instead') Type guard
function isCredentialFreeUrl(url: string): boolean {
try { const u = new URL(url); return !u.username && !u.password } catch { return false }
} Try / catch
try {
await importSource(url)
} catch (err) {
if (err instanceof HTTPError && err.message.includes('must not contain credentials')) {
// strip userinfo and configure authentication via headers/datasource config
}
} Prevention
- Never embed user:pass@ in URLs; use Authorization headers
- Sanitize pasted URLs for userinfo before storing
- Keep datasource credentials in config, not in the import source URL
When it happens
Trigger: Import URLs like https://user:password@api.example.com/data.json where basic-auth credentials are embedded in the URL userinfo component.
Common situations: Copying URLs from tools that embed basic auth in the host part; API providers documenting credential-in-URL access; secrets pasted into the URL field.
Related errors
- Only HTTP(S) URLs are allowed for query import
- Invalid import url
- Invalid object store key: path traversal is not allowed.
- Only HTTP(S) URLs are allowed.
- URL must not include credentials.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/e9e802eb9b3230a6.
Report an issue: GitHub.