RocketChat/Rocket.Chat · error · Meteor.Error
error-avatar-invalid-content-type
error-avatar-invalid-content-type
Error message
Invalid avatar content type
What it means
When service === 'rest', setUserAvatar passes the payload bytes through as-is and requires the caller to supply an explicit contentType; there is no content sniffing on this path. A missing/falsy contentType throws error-avatar-invalid-content-type before any data is parsed. This is the path used by REST avatar uploads (users.setAvatar with a binary body).
Source
Thrown at apps/meteor/server/lib/users/setUserAvatar.ts:170
msg: 'Not a valid content-type from the provided avatar url',
contentType,
url: dataURI,
});
throw new Meteor.Error('error-avatar-invalid-url', `Invalid avatar URL: ${dataURI}`, {
function: 'setUserAvatar',
url: dataURI,
});
}
return {
buffer: Buffer.from(await response.arrayBuffer()),
type: response.headers.get('content-type') || '',
};
}
if (service === 'rest') {
if (!contentType) {
throw new Meteor.Error('error-avatar-invalid-content-type', 'Invalid avatar content type', {
function: 'setUserAvatar',
});
}
return {
buffer: typeof dataURI === 'string' ? Buffer.from(dataURI, 'binary') : dataURI,
type: contentType,
};
}
const fileData = RocketChatFile.dataURIParse(dataURI);
return {
buffer: Buffer.from(fileData.image, 'base64'),
type: fileData.contentType,
};
})();
View on GitHub (pinned to b2c16d5842)
Solutions
- Always send a valid image Content-Type header (e.g. image/png) with avatar upload requests.
- In server code using the 'rest' service, pass contentType explicitly as the third argument.
- Validate that the value is an image/* type before calling setUserAvatar.
Example fix
// before await setUserAvatar(user, buffer, undefined, 'rest'); // after await setUserAvatar(user, buffer, 'image/png', 'rest');
Defensive patterns
Strategy: validation
Validate before calling
if (service === 'rest' && (!contentType || !contentType.startsWith('image/'))) {
throw new Meteor.Error('error-avatar-invalid-content-type', 'Invalid avatar content type');
}
await setUserAvatar(user, buffer, contentType, 'rest'); Type guard
const isImageContentType = (ct?: string | null): ct is string =>
typeof ct === 'string' && ct.split(';')[0].trim().toLowerCase().startsWith('image/'); Prevention
- Always forward the request's Content-Type header when proxying avatar uploads.
- Default to a known type (e.g. image/png) only when you actually know the bytes' format.
- In server code, never call setUserAvatar with service 'rest' without the contentType argument.
When it happens
Trigger: REST avatar upload where the request Content-Type header is missing or was stripped by a proxy and not forwarded into setUserAvatar; programmatic server code calling setUserAvatar(user, buffer, undefined, 'rest').
Common situations: Client-side proxy or gateway stripping Content-Type from forwarded requests; custom integrations sending a raw Buffer without specifying its type; multipart handling losing the part's content type before calling the setter.
Related errors
- emoji-is-not-image
- error-no-file-uploaded
- invalid-field-content
- error-message-size-exceeded
- error-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/4dae6f12f7e487c4.
Report an issue: GitHub.