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

  1. Always send a valid image Content-Type header (e.g. image/png) with avatar upload requests.
  2. In server code using the 'rest' service, pass contentType explicitly as the third argument.
  3. 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

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


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/4dae6f12f7e487c4. Report an issue: GitHub.