JWT Payload Overflow: ERR_RESPONSE_HEADERS_TOO_BIG due to Base64 Encoded Images in User Claims #2973

Open
opened 2026-03-13 10:31:31 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @JeroenVandenabeele on GitHub (Mar 3, 2026).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  • Configure an auth provider that returns a large Base64 encoded image string in the user's profile data (claims).
  • Attempt to sign in via this provider.
  • Upon successful authentication and redirection back to the application, the browser will fail to load the page.
  • Check the browser console/network tab to see the ERR_RESPONSE_HEADERS_TOO_BIG error.
Image

Current vs. Expected behavior

Current Behavior: The current behavior allows for large Base64 encoded images to be sent from an OAuth provider. These large images are stored as a Base64 string directly within the user's data. This can potentially cause a system failure, such as the ERR_RESPONSE_HEADERS_TOO_BIG error, if the user data becomes too large for headers.

Expected Behavior: The expected behavior would automatically handle and sanitize large Base64 image strings. Better Auth should ideally include a built-in feature or plugin that intercepts any user.image claim coming in as a Base64 string. It would then offload the storage of this image to an external provider (like S3 or Cloudinary), and replace the Base64 string with the public URL of the uploaded image before the user profile is persisted or the session is created. This would maintain a small session payload and prevent ERR_RESPONSE_HEADERS_TOO_BIG.

Image

What version of Better Auth are you using?

1.5.2

System info

/

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @JeroenVandenabeele on GitHub (Mar 3, 2026). ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce - Configure an auth provider that returns a large Base64 encoded image string in the user's profile data (claims). - Attempt to sign in via this provider. - Upon successful authentication and redirection back to the application, the browser will fail to load the page. - Check the browser console/network tab to see the ERR_RESPONSE_HEADERS_TOO_BIG error. <img width="648" height="597" alt="Image" src="https://github.com/user-attachments/assets/3bd544a3-8f07-45bd-8573-9a3038f9db84" /> ### Current vs. Expected behavior Current Behavior: The current behavior allows for large Base64 encoded images to be sent from an OAuth provider. These large images are stored as a Base64 string directly within the user's data. This can potentially cause a system failure, such as the ERR_RESPONSE_HEADERS_TOO_BIG error, if the user data becomes too large for headers. Expected Behavior: The expected behavior would automatically handle and sanitize large Base64 image strings. Better Auth should ideally include a built-in feature or plugin that intercepts any user.image claim coming in as a Base64 string. It would then offload the storage of this image to an external provider (like S3 or Cloudinary), and replace the Base64 string with the public URL of the uploaded image before the user profile is persisted or the session is created. This would maintain a small session payload and prevent ERR_RESPONSE_HEADERS_TOO_BIG. <img width="757" height="701" alt="Image" src="https://github.com/user-attachments/assets/85b4fae4-35af-482f-8261-79143a907765" /> ### What version of Better Auth are you using? 1.5.2 ### System info ```bash / ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the enhancementbug labels 2026-03-13 10:31:31 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 3, 2026):

Hi @JeroenVandenabeele! I'm Dosu and I’m helping the better-auth team.

This is a known issue, particularly with providers like Microsoft that return Base64-encoded profile images. Here are the current workarounds:

1. Transform the image in mapProfileToUser (recommended approach):

socialProviders: {
  yourProvider: {
    mapProfileToUser: async (profile) => {
      let imageUrl = profile.image;
      
      // If Base64 image, upload to CDN and get URL
      if (imageUrl?.startsWith('data:image')) {
        imageUrl = await uploadBase64ImageToCDN(imageUrl);
      }
      
      return {
        ...profile,
        image: imageUrl,
      };
    },
  },
}

2. Use databaseHooks for a more centralized approach:

databaseHooks: {
  user: {
    create: {
      before: async (user) => {
        if (user.image?.startsWith('data:image')) {
          const uploadedUrl = await uploadImageToCDN(user.image);
          return { data: { ...user, image: uploadedUrl } };
        }
      },
    },
  },
}

3. Provider-specific options - For Microsoft specifically, you can disable the profile photo:

socialProviders: {
  microsoft: {
    disableProfilePhoto: true,
  },
}

4. Disable cookie cache as a quick workaround (though this requires DB queries for every session check):

session: {
  cookieCache: {
    enabled: false,
  },
}

Note: The returned: false field attribute only works for custom fields, not built-in fields like image, so that won't help here.

Related issue: #5378 tracks a similar problem with Microsoft OAuth.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Mar 3, 2026): <!-- Greeting --> Hi @JeroenVandenabeele! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known issue, particularly with providers like Microsoft that return Base64-encoded profile images. Here are the current workarounds: **1. Transform the image in `mapProfileToUser`** (recommended approach): ```typescript socialProviders: { yourProvider: { mapProfileToUser: async (profile) => { let imageUrl = profile.image; // If Base64 image, upload to CDN and get URL if (imageUrl?.startsWith('data:image')) { imageUrl = await uploadBase64ImageToCDN(imageUrl); } return { ...profile, image: imageUrl, }; }, }, } ``` **2. Use `databaseHooks`** for a more centralized approach: ```typescript databaseHooks: { user: { create: { before: async (user) => { if (user.image?.startsWith('data:image')) { const uploadedUrl = await uploadImageToCDN(user.image); return { data: { ...user, image: uploadedUrl } }; } }, }, }, } ``` **3. Provider-specific options** - For Microsoft specifically, you can [disable the profile photo](https://github.com/better-auth/better-auth/issues/5378#issuecomment-3747925360): ```typescript socialProviders: { microsoft: { disableProfilePhoto: true, }, } ``` **4. Disable cookie cache** as a quick workaround (though this requires DB queries for every session check): ```typescript session: { cookieCache: { enabled: false, }, } ``` Note: The `returned: false` field attribute [only works for custom fields, not built-in fields like `image`](https://github.com/better-auth/better-auth/issues/5378#issuecomment-3747925360), so that won't help here. Related issue: [#5378](https://github.com/better-auth/better-auth/issues/5378) tracks a similar problem with Microsoft OAuth. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/661be640-2f03-4528-850b-d2e14bf77649?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20known%20issue%2C%20particularly%20with%20providers%20like%20Microsoft%20that%20return%20Base64-encoded%20profile%20images.%20Here%20are%20the%20current%20workarounds%3A%0A%0A%2A%2A1.%20Transform%20the%20image%20in%20%60mapProfileToUser%60%2A%2A%20%28recommended%20approach%29%3A%0A%60%60%60typescript%0AsocialProviders%3A%20%7B%0A%20%20yourProvider%3A%20%7B%0A%20%20%20%20mapProfileToUser%3A%20async%20%28profile%29%20%3D%3E%20%7B%0A%20%20%20%20%20%20let%20imageUrl%20%3D%20profile.image%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20//%20If%20Base64%20image%2C%20upload%20to%20CDN%20and%20get%20URL%0A%20%20%20%20%20%20if%20%28imageUrl%3F.startsWith%28%27data%3Aimage%27%29%29%20%7B%0A%20%20%20%20%20%20%20%20imageUrl%20%3D%20await%20uploadBase64ImageToCDN%28imageUrl%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20...profile%2C%0A%20%20%20%20%20%20%20%20image%3A%20imageUrl%2C%0A%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%7D%2C%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0A%2A%2A2.%20Use%20%60databaseHooks%60%2A%2A%20for%20a%20more%20centralized%20approach%3A%0A%60%60%60typescript%0AdatabaseHooks%3A%20%7B%0A%20%20user%3A%20%7B%0A%20%20%20%20create%3A%20%7B%0A%20%20%20%20%20%20before%3A%20async%20%28user%29%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20%28user.image%3F.startsWith%28%27data%3Aimage%27%29%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20uploadedUrl%20%3D%20await%20uploadImageToCDN%28user.image%29%3B%0A%20%20%20%20%20%20%20%20%20%20return%20%7B%20data%3A%20%7B%20...user%2C%20image%3A%20uploadedUrl%20%7D%20%7D%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%7D%2C%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0A%2A%2A3.%20Provider-specific%20options%2A%2A%20-%20For%20Microsoft%20specifically%2C%20you%20can%20%5Bdisable%20the%20profile%20photo%5D%28https%3A//github.com/better-auth/better-auth/issues/5378%23issuecomment-3747925360%29%3A%0A%60%60%60typescript%0AsocialProviders%3A%20%7B%0A%20%20microsoft%3A%20%7B%0A%20%20%20%20disableProfilePhoto%3A%20true%2C%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0A%2A%2A4.%20Disable%20cookie%20cache%2A%2A%20as%20a%20quick%20workaround%20%28though%20this%20requires%20DB%20queries%20for%20every%20session%20check%29%3A%0A%60%60%60typescript%0Asession%3A%20%7B%0A%20%20cookieCache%3A%20%7B%0A%20%20%20%20enabled%3A%20false%2C%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0ANote%3A%20The%20%60returned%3A%20false%60%20field%20attribute%20%5Bonly%20works%20for%20custom%20fields%2C%20not%20built-in%20fields%20like%20%60image%60%5D%28https%3A//github.com/better-auth/better-auth/issues/5378%23issuecomment-3747925360%29%2C%20so%20that%20won%27t%20help%20here.%0A%0ARelated%20issue%3A%20%5B%235378%5D%28https%3A//github.com/better-auth/better-auth/issues/5378%29%20tracks%20a%20similar%20problem%20with%20Microsoft%20OAuth.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/8338)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2973