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

  1. Treat as a sign the origin is untrustworthy — do not retry the same URL, surface the failure.
  2. Mirror a known-good avatar from a trusted source instead of the failing URL.
  3. If recurring for one provider, file a bug with the provider about Content-Length accuracy.
  4. 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

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


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/ad06551b9b57e0a3. Report an issue: GitHub.