Budibase/budibase · error · HTTPError
License key has already been activated
Error message
License key has already been activated
What it means
Thrown by activateLicenseKey when POST /api/license/activate responds with 409 Conflict — the license key has already been activated against another (or the same) installation. The portal enforces one activation per key, so re-activating the same key elsewhere conflicts with the existing binding.
Source
Thrown at packages/pro/src/sdk/licensing/licenses/client.ts:243
const body: LicenseActivateRequest = {
installVersion: install.version,
installId: install.installId,
}
const response = await api.post(`/api/license/activate`, {
headers: {
[constants.Header.LICENSE_KEY]: licenseKey,
},
body,
})
// don't propagate the 403 to prevent logout
if (response.status === 403) {
throw new HTTPError("Invalid license key", 400)
}
if (response.status === 409) {
throw new HTTPError("License key has already been activated", 409)
}
if (response.status !== 200) {
const message = await getResponseErrorMessage(response)
throw new HTTPError(
`Error activating license key: ${message}`,
response.status
)
}
return response.json()
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Check if the key is already active on this install — if the install already works, skip activation and just fetch the license.
- Deactivate the license on the old installation (or via the account portal) before reactivating on the new one.
- Contact Budibase support to reset the activation binding if the old install is gone/unrecoverable.
- Use a distinct license key per environment (dev/staging/prod) instead of sharing one key.
Example fix
// before
await activateLicenseKey(key) // throws 409 on retry
// after
try {
await activateLicenseKey(key)
} catch (e) {
if (e instanceof HTTPError && e.status === 409) {
console.warn("Key already activated — fetching existing license instead")
await getLicenseFromKey(key)
} else {
throw e
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before activating, check whether this install already has a working license
const existing = await getLicenseFromKey(key)
if (existing) { /* already activated — skip activateLicenseKey */ } Type guard
function isAlreadyActivated(e: unknown): boolean {
return e instanceof HTTPError && e.status === 409
} Try / catch
try {
await activateLicenseKey(key)
} catch (e) {
if (isAlreadyActivated(e)) {
// treat as success or fetch existing license instead of rethrowing
} else throw e
} Prevention
- Treat 409 as idempotent success when re-running activation scripts.
- Deactivate licenses on decommissioned installs before migrating.
- Never share one license key across dev/staging/prod.
- After restores that change installId, reissue rather than re-activate the same key.
When it happens
Trigger: Calling activateLicenseKey(licenseKey) for a key already bound to an installId — e.g. activating on a second environment, re-running activation after a restore with a changed installId, or a stale portal record.
Common situations: Migrating Budibase to a new server without deactivating the old one; restoring a backup where the installId changed; CI/test environments sharing a production license key; duplicate activation attempts after a network timeout that actually succeeded.
Related errors
- Invalid license key
- Error activating license key: ${message}
- Unable to bulk remove documents: ${res.error}
- Unable to remove top level directory - some skeleton files a
- Audit logs not available - license required.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/d4f5c8f9e736589d.
Report an issue: GitHub.