Resolve user settings once per page render - #291066
elena-shostak merged 4 commits into
Conversation
The rendering service fetched dark mode and locale through two separate user settings calls inside the same Promise.all. Each call resolves the current user profile independently, so for requests authenticated with Basic credentials and no session both calls activated the same profile concurrently and raced on the .security-profile index, surfacing as 409 version conflicts logged at ERROR. Expose a single getUserSettings lookup on the user settings service and use it from the rendering service so a page render performs one profile lookup. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Selected for Libra reviewThis PR was selected for Libra review as part of the temporary 50% trial. To opt out permanently, remove the |
|
Pinging @elastic/kibana-core (Team:Core) |
kibanamachine
left a comment
There was a problem hiding this comment.
Libra found 1 issue.
Generated by Libra
jeramysoucy
left a comment
There was a problem hiding this comment.
LGTM! Approving, but before you merge the Libra review is worth looking at: #291066 (comment)
And 1 nit: getUserSettingLocale and getUserSettingRememberSelectedSpace have no production callers left after this. Should these be removed?
…op dead getters Add rendering_service tests asserting getUserSettings is called exactly once per authenticated render and not at all for anonymous renders. Remove the getUserSettingLocale and getUserSettingRememberSelectedSpace methods from the InternalUserSettingsServiceSetup interface and implementation; they have no production callers since rendering switched to the combined getUserSettings. Update the mock and service tests accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
💛 Build succeeded, but was flaky
Failed CI Steps
Metrics [docs]
Test Failures
History
|
|
Starting backport for target branches: 8.19, 9.4, 9.5 |
💔 All backports failed
Manual backportTo create the backport manually run: Questions ?Please refer to the Backport tool documentation |
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
|
9.5 is the only version we need to backport this |
|
Starting backport for target branches: 9.5 |
Summary
Fixes a race in server-side page rendering that triggers duplicate user profile activations.
RenderingService.renderresolves the current user's dark mode and locale through two separate calls on the user settings service (getUserSettingDarkModeandgetUserSettingLocale) inside the samePromise.all. Each call performs its ownuserProfile.getCurrentlookup. For a request authenticated withAuthorization: Basicand no session cookie,getCurrentactivates the user profile on every call, so a single page render fired two concurrentactivateUserProfilewrites for the same profile document. The two writes race on.security-profile-8, and when one loses Elasticsearch returns a 409 version conflict that Kibana logs atERRORbefore retrying:The retry always succeeds, so this is log noise rather than a functional failure, but it fires on every basic-auth page load (for example, health checks or probes hitting an app URL with credentials). The second lookup was introduced with the per-user locale setting in 9.5.0.
Changes
UserSettingsServiceexposes a singlegetUserSettings(request)that performs one profile lookup and returns dark mode, locale, and remember-selected-space together. The existing single-value getters delegate to it.RenderingServicecallsgetUserSettingsonce and reads both values from the result.How to verify
Enable
plugins.security.user-profileatdebug, then request a page with basic credentials and no cookie:Before: two
Activating user profile via password grantlines per request. After: one.Release note
Fixed duplicate user profile activations during page rendering for requests authenticated with basic credentials, which could log spurious
version_conflict_engine_exceptionerrors.Checklist
release_note:*label is applied per the guidelinesbackport:*labels.🤖 Generated with Claude Code