Budibase/budibase · error · InvalidAPIKeyWarning
invalid_api_key
invalid_api_key
Error message
Invalid API key
What it means
checkApiKey in the authenticated middleware validates the API key header against known users/tenants; when no matching user is found it throws InvalidAPIKeyWarning with code 'invalid_api_key'. The presented key is syntactically present but not recognized.
Source
Thrown at packages/backend-core/src/middleware/authenticated.ts:95
{
key: apiKey,
},
db
)) as string
} catch (err) {
userId = undefined
}
if (userId) {
return {
valid: true,
user: await getUser({
userId,
tenantId,
populateUser,
}),
}
} else {
throw new InvalidAPIKeyWarning()
}
})
}
function getHeader(ctx: Ctx, header: Header): string | undefined {
const contents = ctx.request.headers[header]
if (Array.isArray(contents)) {
throw new Error("Unexpected header format")
}
return contents
}
/**
* This middleware is tenancy aware, so that it does not depend on other middlewares being used.
* The tenancy modules should not be used here and it should be assumed that the tenancy context
* has not yet been populated.
*/
export function authenticated(View on GitHub (pinned to a81a902e9a)
Solutions
- Regenerate/copy a fresh API key from the app/tenant settings and update the caller
- Confirm the request targets the correct tenant (the key is tenant-scoped)
- Trim whitespace/quotes from the key in env vars or CI secrets
- Check the key wasn't revoked or deleted by another team member
Example fix
// before
headers: { "x-api-key": process.env.OLD_KEY }
// after
headers: { "x-api-key": process.env.BUDIBASE_API_KEY?.trim() } Defensive patterns
Strategy: try-catch
Validate before calling
if (!apiKey || apiKey.trim().length < 10) throw new Error("Provide a valid Budibase API key") Type guard
function isValidApiKey(k: unknown): k is string {
return typeof k === "string" && k.trim().length > 0
} Try / catch
try {
const res = await api.get("/rows", { headers: { "x-api-key": key } })
} catch (e) {
if (e.code === "invalid_api_key") {
key = await fetchFreshApiKey() // regenerate and retry once
} else throw e
} Prevention
- Store keys in one source of truth and update consumers on rotation
- Scope keys per tenant and verify tenant on every call
- Trim and strip quotes from keys read from env/CI secrets
When it happens
Trigger: Sending an API request with an api key header whose value does not match any stored key — revoked keys, wrong tenant, typo'd key, or an old key after regeneration.
Common situations: Rotating keys in the builder but the automation/integration still uses the old one; copying the wrong key between dev/prod tenants; trailing whitespace or quotes around the env-stored key.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unable to retrieve datasource authentication cookie
- Error getting account by email ${email}
- ${err.message}
- Unexpected header format
- Password change is disabled for this user
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/cb7d26ebaca5e672.
Report an issue: GitHub.