danny-avila/LibreChat · warning
Avatar response too large: ${buffer.length} bytes
Error message
Avatar response too large: ${buffer.length} bytes What it means
Defense-in-depth post-read guard: after `response.buffer()` completes, asserts the actual buffer length is within MAX_AVATAR_BYTES (10 MB). This catches origins that lied about Content-Length (or omitted it) and served more bytes than declared. node-fetch's `size` option already aborts oversized reads, but this assert turns the resulting state into an explicit, loggable error.
Source
Thrown at api/server/services/Files/images/avatar.js:70
});
if (!response.ok) {
throw new Error(`Failed to fetch image from URL. Status: ${response.status}`);
}
const contentLength = parseInt(response.headers.get('content-length') ?? '0', 10);
if (contentLength > MAX_AVATAR_BYTES) {
throw new Error(`Avatar response too large: ${contentLength} bytes`);
}
/**
* Re-check after read in case the server lied about Content-Length or
* omitted it. `node-fetch` v2 honors the `size` option above and throws on
* overflow, but Defense-in-depth: assert on the actual buffer length.
*/
const buffer = await response.buffer();
if (buffer.length > MAX_AVATAR_BYTES) {
throw new Error(`Avatar response too large: ${buffer.length} bytes`);
}
return buffer;
}
/**
* Uploads an avatar image for a user. This function can handle various types of input (URL, Buffer, or File object),
* processes the image to a square format, converts it to target format, and returns the resized buffer.
*
* @param {Object} params - The parameters object.
* @param {string} params.userId - The unique identifier of the user for whom the avatar is being uploaded.
* @param {string} options.desiredFormat - The desired output format of the image.
* @param {(string|Buffer|File)} params.input - The input representing the avatar image. Can be a URL (string),
* a Buffer, or a File object.
* @param {{ headers?: Record<string, string> }} [params.fetchOptions] - Optional headers for trusted avatar URLs.
*
* @returns {Promise<any>}
* A promise that resolves to a resized buffer.
*View on GitHub (pinned to 5ff282f900)
Solutions
- Treat as a sign the origin is untrustworthy — do not retry the same URL, surface the failure.
- Mirror a known-good avatar from a trusted source instead of the failing URL.
- If recurring for one provider, file a bug with the provider about Content-Length accuracy.
- Confirm the size cap (10 MB) is appropriate; do not raise it to mask a hostile origin.
Defensive patterns
Strategy: try-catch
Try / catch
try { await fetchAvatarBuffer(url); }
catch (e) {
if (/Avatar response too large/.test(e.message) && e.message.includes('buffer.length')) {
logger.warn('Avatar origin lied about Content-Length', { url });
return res.status(413).json({ error: 'Avatar source is untrustworthy or too large.' });
}
throw e;
} Prevention
- Treat this guard firing as a sign of a hostile or broken origin — don't retry blindly.
- Mirror avatars from trusted providers to your own storage to avoid repeated exposure.
- Log the URL when this fires to spot malicious patterns.
When it happens
Trigger: Server returns `Content-Length: 1024` but streams 50 MB; server omits Content-Length and streams until the connection closes with a payload over 10 MB; chunked transfer-encoding delivering an oversized body.
Common situations: Malicious origins attempting slow-loris-style memory exhaustion via header/body mismatch; misconfigured streaming backends that buffer-then-flush without accurate headers; compromised or buggy image CDNs.
Related errors
- Remote file response too large: ${buffer.length} bytes
- Remote file response too large: ${buffer.length} bytes
- Refusing to fetch avatar over ${parsed.protocol}
- Avatar response too large: ${contentLength} bytes
- User ID not found in blob path
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/ad06551b9b57e0a3.
Report an issue: GitHub.