Repository navigation
Deprecate Builder.customizeRequest() in favor of httpRequestCustomizer() #788
Copy link
Copy link
Closed
Copy link
Labels
P2Moderate issues affecting some users, edge cases, potentially valuable featureModerate issues affecting some users, edge cases, potentially valuable featureenhancementNew feature or requestNew feature or requestwaiting for userWaiting for user feedback or more detailsWaiting for user feedback or more details
Description
Activity
- changed the title
[-]Deprecate `customizeRequest()` — it silently breaks OAuth token refresh[/-][+]Deprecate Builder.customizeRequest() in favor of httpRequestCustomizer()[/+]on Feb 13, 2026 - added 5 commits that reference this issue
on Feb 13, 2026 @Kehrlann when you get a chance please review this issue and the linked PR.
- addedenhancementNew feature or requestNew feature or requestP2Moderate issues affecting some users, edge cases, potentially valuable featureModerate issues affecting some users, edge cases, potentially valuable feature
on Feb 21, 2026 - added a commit that references this issue
on Mar 2, 2026 - addedwaiting for userWaiting for user feedback or more detailsWaiting for user feedback or more detailsand removed
on Mar 4, 2026 - added a commit that references this issue
on Apr 2, 2026 - added 2 commits that reference this issue
on Apr 2, 2026 - added a commit that references this issue
on Apr 10, 2026
Metadata
Metadata
Assignees
Labels
P2Moderate issues affecting some users, edge cases, potentially valuable featureModerate issues affecting some users, edge cases, potentially valuable featureenhancementNew feature or requestNew feature or requestwaiting for userWaiting for user feedback or more detailsWaiting for user feedback or more details
Bug description
Builder.customizeRequest()in bothHttpClientSseClientTransportandHttpClientStreamableHttpTransportexecutes its consumer once at build time, mutating the sharedrequestBuilder. Any headers set here (e.g.,Authorization) are frozen into the template and copied to every subsequent request viarequestBuilder.copy(). They cannot be updated after the transport is built.This becomes a significant issue for OAuth token refresh scenarios: after refreshing an access token, the transport continues sending the old expired token because the header was baked into the request builder at construction time.
The method name
customizeRequeststrongly suggests per-request behavior, making it easy to use incorrectly. The correct alternatives —httpRequestCustomizer()andasyncHttpRequestCustomizer()— already exist and run on every request, but there's no deprecation notice guiding users toward them.Environment
MCP Java SDK (latest main branch). Affects both
HttpClientSseClientTransportandHttpClientStreamableHttpTransport.Steps to reproduce
Expected behavior
Users should be guided toward
httpRequestCustomizer()orasyncHttpRequestCustomizer()for dynamic headers. Ideally,customizeRequest()should be marked@Deprecatedwith clear Javadoc explaining the build-time-only semantics.Real-world impact
We encountered this in production where our MCP connector's OAuth token refresh was completely non-functional:
McpAsyncClientis already initialized)requestBuilderstill has the old token baked in from build timeSwitching from
customizeRequest()tohttpRequestCustomizer()resolved the issue.Additional note
The current Javadoc for
customizeRequest()says "Customizes the HTTP client builder" which is also slightly misleading — it customizes the request builder, not the client builder (that'scustomizeClient()).A PR with the deprecation annotation and updated Javadoc has been submitted: #791