RocketChat/Rocket.Chat · error · Meteor.Error
error-not-allowed
error-not-allowed
Error message
Change avatar is not allowed
What it means
avatarsOnFinishUpload (FileUpload.ts:449-452) runs when a file finishes uploading to the Avatars store. For non-room files (no file.rid) it must bind the avatar to a user; if the upload record has no userId it throws error-not-allowed 'Change avatar is not allowed'. The userId is derived from the upload request's authenticated context, so a missing one means the upload arrived without a valid user.
Source
Thrown at apps/meteor/server/lib/media/file-upload/lib/FileUpload.ts:449
size = await MultipartUploadHandler.stripExifFromFile(tmpFile);
}
await this.getCollection().updateOne(
{ _id: file._id },
{
$set: { size, identify },
},
options,
);
},
async avatarsOnFinishUpload(file: IUpload) {
if (file.rid) {
return;
}
if (!file.userId) {
throw new Meteor.Error('error-not-allowed', 'Change avatar is not allowed');
}
// update file record to match user's username
const user = await Users.findOneById(file.userId);
if (!user?.username) {
throw new Meteor.Error('error-not-allowed', 'Change avatar is not allowed');
}
const oldAvatar = await Avatars.findOneByName(user.username);
if (oldAvatar) {
await Avatars.deleteFile(oldAvatar._id);
}
await Avatars.updateFileNameById(file._id, user.username);
},
async getRequestUserId({ headers = {}, url }: http.IncomingMessage): Promise<string | undefined> {
if (!url) {
return undefined;
}View on GitHub (pinned to b2c16d5842)
Solutions
- Upload avatars through the supported flows: the UI avatar dialog or the users.setAvatar REST endpoint with a valid auth token
- When hitting the raw upload URL, include valid X-User-Id/X-Auth-Token headers or a logged-in cookie session
- Verify the URL you POST to is the one returned by the avatar upload API, not a hand-built one
- If writing server code, ensure the upload record carries userId before the store finishes
Defensive patterns
Strategy: validation
Validate before calling
// before POSTing to the avatar upload URL
const userId = await resolveCurrentUserId();
if (!userId) throw new Error('Avatar upload requires an authenticated user'); Try / catch
try {
await uploadAvatar(file);
} catch (error: any) {
if (error instanceof Meteor.Error && error.error === 'error-not-allowed' && /avatar/i.test(error.reason)) {
reauthenticateAndRetry(); // upload arrived without a user binding
return;
}
throw error;
} Prevention
- Use users.setAvatar instead of the raw upload endpoint
- Always send valid auth headers with file uploads
- Treat a missing userId as a session bug, not a server flake
When it happens
Trigger: POSTing directly to the avatar file-upload URL without X-Auth-Token/X-User-Id headers or a valid session cookie; uploads whose request-user resolution (getRequestUserId) fails because the URL is malformed; anonymous uploads to the Avatars store.
Common situations: Custom scripts calling the raw upload endpoint instead of users.setAvatar; expired auth tokens where the file POST succeeds but the user cannot be resolved; load balancers/proxies stripping auth headers; broken federation/omnichannel avatar flows.
Related errors
- error-invalid-data
- error-avatar-invalid-content-type
- error-invalid-user
- error-invalid-user
- error-invalid-user
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/d1dfa50b23e5f101.
Report an issue: GitHub.