{"record":{"id":"ca5e9dd3c4df69cf","repo":"appwrite/appwrite","slug":"user-id-missing","errorCode":"user_id_missing","errorMessage":"When using account API key, make sure to pass x-appwrite-user header with your user ID.","messagePattern":"When using account API key, make sure to pass x-appwrite-user header with your user ID\\.","errorType":"exception","errorClass":"Appwrite\\Extend\\Exception","httpStatus":403,"severity":"error","filePath":"app/init/resources/request.php","lineNumber":1048,"sourceCode":"        if (empty($key)) {\n            return null;\n        }\n\n        $key = Key::decode($project, $team, $user, $key);\n\n        $userHeader = $request->getHeaderLine('x-appwrite-user');\n        $organizationHeader = $request->getHeaderLine('x-appwrite-organization');\n        $projectHeader = $request->getHeaderLine('x-appwrite-project');\n\n        if (! empty($key->getProjectId())) {\n            if (empty($projectHeader) || $projectHeader !== $key->getProjectId()) {\n                throw new Exception(Exception::PROJECT_ID_MISSING);\n            }\n        }\n\n        if (! empty($key->getUserId())) {\n            if (empty($userHeader) || $userHeader !== $key->getUserId()) {\n                throw new Exception(Exception::USER_ID_MISSING);\n            }\n        }\n\n        if (! empty($key->getTeamId())) {\n            if (empty($organizationHeader) || $organizationHeader !== $key->getTeamId()) {\n                throw new Exception(Exception::ORGANIZATION_ID_MISSING);\n            }\n        }\n\n        return $key;\n    }, ['request', 'project', 'team', 'user']);\n\n    $context->set('resourceToken', function ($project, $dbForProject, $request, Authorization $authorization) {\n        $tokenJWT = $request->getParam('token');\n\n        if (! empty($tokenJWT) && ! $project->isEmpty()) { // JWT authentication\n            // Use a large but reasonable maxAge to avoid auto-exp when token has no expiry\n            $jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), RESOURCE_TOKEN_ALGORITHM, RESOURCE_TOKEN_MAX_AGE, RESOURCE_TOKEN_LEEWAY); // Instantiate with key, algo, maxAge and leeway.","sourceCodeStart":1030,"sourceCodeEnd":1066,"githubUrl":"https://github.com/appwrite/appwrite/blob/cd368e707d4b492bc5e8e9c0f8ecbc5b741c4bf4/app/init/resources/request.php#L1030-L1066","documentation":"Thrown in the account-API-key validator (app/init/resources/request.php:1048) when a decoded API key carries a userId but the x-appwrite-user header is missing or does not match. This binds the account key to the specific user it was issued for.","triggerScenarios":"Client authenticates with an account API key whose payload includes a userId, but x-appwrite-user is absent or mismatched. The check at line ~1046 compares $userHeader !== $key->getUserId().","commonSituations":"SDK not configured to send x-appwrite-user when using an account API key; header stripped by proxy; key for user A used with a client pointing at user B; SSR setup missing the user header.","solutions":["Set x-appwrite-user (client.setHeader or SDK equivalent) to the key's userId.","Confirm the userId in the key matches the user the client means to act as.","Ensure proxies do not strip x-appwrite-user.","If using the SDK, configure it to send both the key and the user header together."],"exampleFix":"// before\nclient.setHeader('x-appwrite-key', accountApiKey);\n// after\nclient.setHeader('x-appwrite-key', accountApiKey);\nclient.setHeader('x-appwrite-user', userId);","handlingStrategy":"validation","validationCode":"// Ensure x-appwrite-user is set whenever an account API key is used\nfunction ensureUserHeader(headers, keyUserId) {\n  if (keyUserId && headers['x-appwrite-user'] !== keyUserId) {\n    headers['x-appwrite-user'] = keyUserId;\n  }\n  return headers;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When using an account API key, always set x-appwrite-user to the key's userId.","Ensure proxies forward x-appwrite-user.","Keep the key and the user header paired in SDK configuration."],"tags":["authentication","api-key","headers","user","http"],"backgroundTag":null,"analyzedSha":"cd368e707d4b492bc5e8e9c0f8ecbc5b741c4bf4","analyzedAt":"2026-08-12T14:42:48.571Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}