RocketChat/Rocket.Chat · warning
The server detected an unauthenticated access to an user ava
Error message
The server detected an unauthenticated access to an user avatar. This type of request will soon be blocked by default.
What it means
Logged (throttled to once per 30 minutes) by userCanAccessAvatar in apps/meteor/server/routes/avatar/utils.ts. When the setting Accounts_AvatarBlockUnauthenticatedAccess is enabled, every avatar request is authenticated via rc_uid + rc_token (headers or query) checked against Users.findOneByIdAndLoginToken(hashLoginToken(rc_token)). If the credentials are absent or invalid, this warning fires — it announces that unauthenticated avatar access, historically allowed, will be blocked by default in a future version.
Source
Thrown at apps/meteor/server/routes/avatar/utils.ts:110
async function isUserAuthenticated({ headers, query }: Pick<IIncomingMessage, 'headers' | 'query'>) {
let { rc_uid, rc_token } = query;
if (!rc_uid && headers.cookie) {
rc_uid = cookie.get('rc_uid', headers.cookie);
rc_token = cookie.get('rc_token', headers.cookie);
}
if (rc_uid == null || rc_token == null) {
return false;
}
const userFound = await Users.findOneByIdAndLoginToken(rc_uid, hashLoginToken(rc_token), { projection: { _id: 1 } }); // TODO memoize find
return !!userFound;
}
const warnUnauthenticatedAccess = throttle(() => {
console.warn('The server detected an unauthenticated access to an user avatar. This type of request will soon be blocked by default.');
}, 60000 * 30); // 30 minutes
export async function userCanAccessAvatar({ headers = {}, query = {} }: IIncomingMessage) {
if (!settings.get('Accounts_AvatarBlockUnauthenticatedAccess')) {
return true;
}
const isAuthenticated = await isUserAuthenticated({ headers, query });
if (!isAuthenticated) {
warnUnauthenticatedAccess();
}
return isAuthenticated;
}
const getFirstLetter = (name: string) => {
const sanitizedName = sanitizeHtml(name);
return sanitizedName.substring(0, 1).toUpperCase();View on GitHub (pinned to b2c16d5842)
Solutions
- Identify the referrers hitting /avatar/* without credentials (access logs) — usually email templates, external sites, or integrations.
- Serve avatars to logged-in clients only: use the authenticated browser session (cookies) or append valid rc_uid + rc_token query params for machine access.
- For emails/external embeds, stop inlining the server avatar URL; use the recipient-side rendered avatar or a public CDN asset instead.
- If anonymous access is an intentional product requirement for your deployment, keep Accounts_AvatarBlockUnauthenticatedAccess = false and document the future behavior change.
Example fix
// before: anonymous embed that triggers the warning once the setting is on
<img src="https://chat.example.com/avatar/john.doe" />
// after: authenticated request with token pair
const url = `https://chat.example.com/avatar/john.doe?rc_uid=${userId}&rc_token=${authToken}`;
// (fetch token via REST login: POST /api/v1/login) Defensive patterns
Strategy: validation
Validate before calling
// Client-side: verify credentials exist before requesting a blocked avatar
const canFetchAvatar = (userId: string | null, token: string | null): boolean =>
userId != null && token != null;
const url = canFetchAvatar(Meteor.userId(), Meteor._localStorage.getItem('Meteor.loginToken'))
? `/avatar/${username}?rc_uid=${Meteor.userId()}&rc_token=${token}`
: null; // fall back to a local placeholder instead of an anonymous request Prevention
- Never embed raw /avatar/<user> URLs in emails or external pages; those requests are anonymous by construction.
- Pass rc_uid and rc_token (or rely on the authenticated session cookie) for every avatar request from scripts and integrations.
- Audit access logs for anonymous /avatar/* traffic BEFORE enabling Accounts_AvatarBlockUnauthenticatedAccess so nothing breaks when it blocks.
When it happens
Trigger: A request to /avatar/<username> (or /avatar/<username>.jpg) arrives with Accounts_AvatarBlockUnauthenticatedAccess = true, and the request carries no rc_uid/rc_token pair, or the token does not hash-match a stored login token for that user. Frequent producers: <img src="/avatar/..."> embedded in emails, external websites, or chat previews; proxies that strip cookies; scrapers and monitoring tools hitting avatar URLs; logged-out pages hotlinking avatars.
Common situations: Administrators enabling Accounts_AvatarBlockUnauthenticatedAccess ahead of the default flip; webhook/notification emails that inline avatar URLs without auth tokens; migrating public workspaces to private ones; CDN caching of avatar URLs that were fetched anonymously. Once the setting blocks, those images return 401/403 instead of rendering.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/a29f5b50ea7f8431.
Report an issue: GitHub.