{"record":{"id":"1a6f7932ab2cdaa3","repo":"langfuse/langfuse","slug":"unauthorized-cannot-use-organization-key-with-bea","errorCode":null,"errorMessage":"Unauthorized: Cannot use organization key with bearer auth","messagePattern":"Unauthorized: Cannot use organization key with bearer auth","errorType":"exception","errorClass":"Error","httpStatus":401,"severity":"error","filePath":"web/src/features/public-api/server/apiAuth.ts","lineNumber":215,"sourceCode":"                rateLimitOverrides: finalApiKey.rateLimitOverrides ?? [],\n                apiKeyId: finalApiKey.id,\n                scope: finalApiKey.scope,\n                publicKey: finalApiKey.publicKey,\n                isIngestionSuspended: finalApiKey.isIngestionSuspended,\n                isInAppAgentKey: finalApiKey.isInAppAgentKey,\n              },\n            };\n\n            return result;\n          }\n          // Bearer auth, limited scope, only needs public key\n          if (authHeader.startsWith(\"Bearer \")) {\n            const publicKey = authHeader.replace(\"Bearer \", \"\");\n\n            const dbKey = await this.findDbKeyOrThrow(publicKey);\n\n            if (dbKey.scope === \"ORGANIZATION\") {\n              throw new Error(\n                \"Unauthorized: Cannot use organization key with bearer auth\",\n              );\n            }\n\n            const { orgId, cloudConfig, cloudFreeTierUsageThresholdState } =\n              this.extractOrgIdAndCloudConfig(dbKey);\n            const plan = getOrganizationPlanServerSide(cloudConfig);\n\n            addUserToSpan(\n              {\n                projectId: dbKey.projectId ?? undefined,\n                orgId,\n                plan,\n                apiKeyId: dbKey.id,\n                publicKey: dbKey.publicKey,\n              },\n              span,\n            );","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/langfuse/langfuse/blob/59d92c7cf365150d10b753b5a0d1708902a2ed60/web/src/features/public-api/server/apiAuth.ts#L197-L233","documentation":"Error thrown when a Bearer-auth request resolves to an ORGANIZATION-scoped key: organization keys must not be used with bearer auth on these endpoints, since org keys authorize differently than project keys.","triggerScenarios":"Sending 'Authorization: Bearer <org-scoped key>' (e.g., an org-level ingestion key like laingub-... used as a bearer token) to an endpoint handled by verifyAuthHeaderAndReturnScope.","commonSituations":"Org-wide keys generated for OTLP ingestion reused for API calls; new org key feature adopted by scripts that previously used project bearer keys.","solutions":["Use a project-scoped key with Bearer auth for these calls","Use the org key only with the ingestion endpoints that accept it","Switch to Basic auth with a project secret key for management APIs"],"exampleFix":"// before\nAuthorization: Bearer <org-key>\n// after\nAuthorization: Bearer <project-scoped-key>","handlingStrategy":"type-guard","validationCode":"// Determine key scope before choosing auth scheme\nif (key.scope === 'ORGANIZATION') {\n  // org keys are for ingestion endpoints only; use a project key here\n  key = getProjectKey();\n}","typeGuard":"const isOrgScoped = (k: {scope: string}) => k.scope === 'ORGANIZATION';","tryCatchPattern":"try {\n  await fetch('/api/public/...', { headers: { Authorization: `Bearer ${token}` } });\n} catch (e) {\n  if (e.message.includes('organization key with bearer auth')) {\n    // swap to a project-scoped bearer key or Basic sk- auth\n  }\n}","preventionTips":["Label org keys clearly as ingestion-only in your config","Maintain separate env vars for org ingestion keys vs project API keys"],"tags":["auth","bearer","organization-scope","public-api"],"backgroundTag":"insufficient-api-key-scope","analyzedSha":"59d92c7cf365150d10b753b5a0d1708902a2ed60","analyzedAt":"2026-08-27T22:22:00.402Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}