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

  1. Regenerate/copy a fresh API key from the app/tenant settings and update the caller
  2. Confirm the request targets the correct tenant (the key is tenant-scoped)
  3. Trim whitespace/quotes from the key in env vars or CI secrets
  4. 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

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

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/cb7d26ebaca5e672. Report an issue: GitHub.