RocketChat/Rocket.Chat · error · Meteor.Error
error-avatar-invalid-url
error-avatar-invalid-url
Error message
Invalid avatar URL: ${dataURI} What it means
With service 'url', the server fetches the avatar URL with SSRF validation enabled (private/loopback addresses blocked unless present in the SSRF_Allowlist setting). If the fetch itself throws — DNS failure, connection refused, TLS error, or an SSRF-blocked address — error-avatar-invalid-url is thrown; the underlying err is logged via SystemLogger ('Not a valid response from the avatar url').
Source
Thrown at apps/meteor/server/lib/users/setUserAvatar.ts:117
return;
}
const { buffer, type } = await (async (): Promise<{ buffer: Buffer; type: string }> => {
if (service === 'url' && typeof dataURI === 'string') {
let response: Response;
try {
response = await fetch(dataURI, {
ignoreSsrfValidation: false,
allowList: settings.get<string>('SSRF_Allowlist'),
});
} catch (e) {
SystemLogger.info({
msg: 'Not a valid response from the avatar url',
url: dataURI,
err: e,
});
throw new Meteor.Error('error-avatar-invalid-url', `Invalid avatar URL: ${dataURI}`, {
function: 'setUserAvatar',
url: dataURI,
});
}
if (response.status !== 200) {
if (response.status !== 404) {
SystemLogger.info({
msg: 'Error while handling the setting of the avatar from a url',
url: dataURI,
username: user.username,
status: response.status,
});
throw new Meteor.Error(
'error-avatar-url-handling',
`Error while handling avatar setting from a URL (${dataURI}) for ${user.username}`,
{ function: 'RocketChat.setUserAvatar', url: dataURI, username: user.username },
);View on GitHub (pinned to 2a7de45707)
Solutions
- Use a publicly reachable https URL that serves the image directly.
- For legitimate internal hosts, add them to the SSRF_Allowlist setting.
- Check server logs for the 'Not a valid response from the avatar url' entry to see the true fetch error (DNS vs SSRF vs TLS).
- Verify DNS resolution and egress from the Rocket.Chat server host itself (curl the URL from that machine).
Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap client-side pre-checks; the server fetch is the authority
import { isURL } from 'validator';
const isValidAvatarUrl = (url: string): boolean =>
isURL(url, { protocols: ['http', 'https'], require_protocol: true }) &&
!/^(https?:\/\/)?(localhost|127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/.test(url); // SSRF-blocked ranges Type guard
const isPublicHttpUrl = (url: string): boolean => {
try {
const u = new URL(url);
return (u.protocol === 'http:' || u.protocol === 'https:') && !isPrivateHostname(u.hostname);
} catch {
return false;
}
}; Try / catch
try {
await setUserAvatar(user, url, undefined, 'url');
} catch (e: any) {
if (e.error === 'error-avatar-invalid-url') {
logger.warn({ msg: 'Avatar URL unreachable or SSRF-blocked', url: e.details?.url });
return setUserAvatar(user, '', undefined, 'initials'); // fall back to initials avatar
}
throw e;
} Prevention
- Only submit avatar URLs the server can reach: public https links, or internal hosts explicitly added to SSRF_Allowlist.
- Do not assume a URL that loads in the browser is loadable from the server.
- For internal images, upload the bytes (data-URI/rest) instead of the URL.
- Check SystemLogger for the underlying fetch error before assuming the URL string is wrong.
When it happens
Trigger: Avatar URL unreachable from the server (reachable from the browser is not enough); http://localhost/... or 10.x/192.168.x addresses blocked by SSRF protection; typo'd domain (DNS failure); expired TLS certificate on the image host; firewall blocking server egress.
Common situations: Client passes an intranet/internal-CDN URL the public server cannot reach; developers testing with localhost image links; internal host not added to SSRF_Allowlist; image domain expired or DNS records removed.
Related errors
- error-avatar-url-handling
- App package download failed
- App metadata download failed
- error-ai-provider-request-failed
- Connection_failed
AI-assisted analysis of RocketChat/Rocket.Chat@2a7de45707 (2026-08-18).
Data as JSON: /api/errors/068003c6903d4e15.
Report an issue: GitHub.