Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected message id from the client (sync ids different) #12640

Open
thomaskiesl opened this issue Dec 27, 2021 · 39 comments
Open

Unexpected message id from the client (sync ids different) #12640

thomaskiesl opened this issue Dec 27, 2021 · 39 comments

Comments

@thomaskiesl
Copy link

thomaskiesl commented Dec 27, 2021

Description of the bug

I receive sometimes the same error message on my production system. But I do not have any idea when this happen:

2021-12-27 07:27:43,174 INFO | https-jsse-nio-18443-exec-10 | com.vaadin.flow.server.communication.ServerRpcHandler | Ignoring old duplicate message from the client. Expected: 1748, got: 1747

2021-12-27 07:28:01,354  WARN | https-jsse-nio-18443-exec-5 | de.app.ApplicationVaadinServiceInitListener         | Unexpected error
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 1751, got 1752. more details logged on DEBUG level.
        at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:310)
        at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:115)
        at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
        at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1565)
        at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:302)
        at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)

It seems it is the same bug as #9778

Minimal reproducible example

Unfortunately I'm not possible to reproduce the issue. I only find the messages in the logfile.

Versions

  • Vaadin / Flow version: 21.0.9
  • Java version: 17.0.1
  • OS version: CentOS
@thomaskiesl
Copy link
Author

Currently I find this issue ~10-20 per day in my logfile. Unfortunately I have no idea where this is coming from. The problem is that everytime a error message is shown to the user...

@thomaskiesl
Copy link
Author

thomaskiesl commented Jan 2, 2022

I activated the debug logging, and got the following (unfortunately no special information):

2022-01-02 20:25:10,673 DEBUG | https-jsse-nio-18443-exec-9 | com.vaadin.flow.server.communication.ServerRpcHandler | Unexpected message id from the client. Expected sync id: 2, got 1. Message start:

2022-01-02 20:25:10,685  WARN | https-jsse-nio-18443-exec-9 | de.app.AppVaadinServiceInitListener         | Unexpected error
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 1. more details logged on DEBUG level.
        at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:310)
        at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:115)
        at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
        at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1565)
        at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:302)
        at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:109)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)

@thomaskiesl
Copy link
Author

thomaskiesl commented Jan 2, 2022

Additional info: Once today I got the following message:

2022-01-02 20:25:09,626 INFO | https-jsse-nio-18443-exec-7 | com.vaadin.flow.server.communication.ServerRpcHandler | Ignoring old duplicate message from the client. Expected: 1, got: 0

and some milliseconds after "Unexpected message id from the client. Expected sync id: 2, got 1. more details logged on DEBUG level." the following:

2022-01-02 20:25:11,225 WARN | https-jsse-nio-18443-exec-7 | com.vaadin.flow.server.communication.ServerRpcHandler | Resynchronizing UI by client's request. Under normal operations this should not happen and may indicate a bug in Vaadin platform. If you see this message regularly please open a bug report at https://github.com/vaadin/flow/issues

@caalador
Copy link
Contributor

caalador commented Jan 4, 2022

Without only this information it would feel like one server message to the client is lost as the server should for each response send a syncId that it expects the client to have in the next request. In short:

The server generates a strictly increasing id for each response to each
request from the client. This ID is then replayed back to the server on
each request. This helps the server in knowing in what state the client
is, and compare it to its own state. In short, it helps with concurrent
changes between the client and server.

Without any way to reproduce this is really hard to investigate. @Legioth would you have any ideas on how @thomaskiesl could try to investigate the issue on their end?

@thomaskiesl
Copy link
Author

Does anyone have an idea how to find this out? I got this message every day multiple times? Additional logging?

@Legioth
Copy link
Member

Legioth commented Jan 26, 2022

There's supposed to be some additional information about the message payload after Message start: in the thing that is logged on the debug level. Looking at that data might reveal some pattern in the messages that cause the problem. Looking at the code, there is also a possibility that nothing is actually logged - this would happen in the theoretical case with an empty array in the message.

There are a couple of possible causes for why old sequence numbers would show up unexpectedly. Finding out the cause is usually very difficult without a good way of reproducing.

  • The browser might for some reason retry sending the message in case it didn't receive a response.
  • An HTTP proxy or similar in between might do the same.
  • There's a possibility that these aren't actually sequence mismatches, but instead somehow mixing up sessions or UI instances. It would on the other hand be expected to also see mismatches in the other direction then, i.e. messages where the received sequence number is greater than the expected number.

@thomaskiesl
Copy link
Author

@Legioth I recevie for example the following info within the debug file:

 Unexpected message id from the client. Expected sync id: 34, got 35. Message start: { type: event node: 1.0 feature: null }
 Unexpected message id from the client. Expected sync id: 34, got 35. more details logged on DEBUG level.

@giorgiac98
Copy link

I'm experiencing this issue too, same vaadin version
[com.vaadin.flow.server.DefaultErrorHandler] (default task-359) : java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 5, got 2. Message start: {"csrfToken":"ac311843-2839-4ffe-878c-256d7f69ae7a",rpc":[],"syncId":3,"clientId":2,"resynchronize":true}

@sergiupienar
Copy link

sergiupienar commented Apr 22, 2022

Also getting this on Vaadin 14.7.0. Upon getting this it leads to an internal error page on the UI.

Uncaught UI exception: java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 41, got 39. Message start: {"csrfToken":"7f83ca3d-e864-4362-9dda-a8af3e641780","rpc":[],"syncId":52,"clientId":39,"resynchronize":true}
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:310)
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:92)

I was able to replicate it by setting up a Chrome network throttling profile with a Download of 100 kbits/s, Upload of 50 kbits/s and a latency of 500.

Then I quickly clicked on a paged table's paginator so that it would change pages and data being fetched and from time to time clicked on a row on the table. After a minute or so the UI went blank while the server log showed

[com.business.ui.MainLayout] (default task-74) Uncaught UI exception: java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 135, got 126. Message start: {"csrfToken":"e92cd975-d064-4551-9277-59b21ca057c1","rpc":[{"type":"publishedEventHandler","node":844,"templateEventMethodName":"deselect","templateEventMethodArgs":["215"],"promise":188},{"type":"publishedEventHandler","node":844,"templateEventMethodName":"setDetailsVisible","templateEventMethodArgs":[null],"promise":189},{"type":"event","node":844,"event":"item-click","data":{"event.detail.screenY":511,"event.detail.metaKey":false,"event.detail.button":0,"event.detail.shiftKey":false,"event.detail.screenX":1024,"event.detail.itemKey":"215","event.detail.internalColumnId":"col6","event.detail.altKey":false,"event.detail.clientX":1024,"event.detail.detail":1,"event.detail.clientY":408,"event.detail.ctrlKey":false}},{"type":"publishedEventHandler","node":844,"templateEventMethodName":"select","templateEventMethodArgs":["216"],"promise":190},{"type":"publishedEventHandler","node":844,"templateEventMethodName":"setDetailsVisible","templateEventMethodArgs":["216"],"promise":191},{"type":"e
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:310)

Before that I also see some

2022-04-22 06:08:41,376 WARN  [com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler] (default task-74) Got an RPC for non-existent node: 844

messages in the logs.

Issue seems to be related to #9778

@funfried
Copy link

I'm using Vaadin 24.2.3 with Java 21, SpringBoot 3.2 and Spring Framework 6.1 (on macOS Ventura 13.5) and still see this issue:

java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 13, got 14. more details logged on DEBUG level.
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:313)
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:114)
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1522)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398)
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:642)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:408)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:313)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:277)
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141)
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:178)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:125)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.security.web.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:479)
	at org.springframework.security.web.ObservationFilterChainDecorator.lambda$wrapUnsecured$1(ObservationFilterChainDecorator.java:90)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:219)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at java.base\/java.lang.VirtualThread.run(VirtualThread.java:311)

Any news on this?

Cheers,
Fabian

@uweschaefer
Copy link

Same problem here on JDK17, vaadin 24.1.11, SB3.1 - fairly trivial application. 20% of e2e-Tests fail randomly with something similar to

023-11-29T20:59:15.336Z ERROR 3414 --- [o-auto-1-exec-2] c.v.flow.server.DefaultErrorHandler      : 

java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 3. more details logged on DEBUG level.
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:313) ~[flow-server-24.1.13.jar:24.1.13]
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:114) ~[flow-server-24.1.13.jar:24.1.13]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-24.1.13.jar:24.1.13]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1529) ~[flow-server-24.1.13.jar:24.1.13]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398) ~[flow-server-24.1.13.jar:24.1.13]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106) ~[vaadin-spring-24.1.13.jar:na]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.15.jar:6.0]

@manpreetsoftodia
Copy link

Same issue for me on vaadin version= 24.2.6 and springboot=3.0.6

2023-12-14T05:46:52.970Z ERROR 117 --- [http-nio-80-exec-9] c.v.flow.server.DefaultErrorHandler      :
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 3. more details logged on DEBUG level.at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:313) ~[flow-server-24.2.5.jar!/:24.2.5]at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:114) ~[flow-server-24.2.5.jar!/:24.2.5]at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-24.2.5.jar!/:24.2.5]at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1522) ~[flow-server-24.2.5.jar!/:24.2.5]at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398) ~[flow-server-24.2.5.jar!/:24.2.5]at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106) ~[vaadin-spring-24.2.5.jar!/:na]at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.8.jar!/:na]at 

@leandropnto
Copy link

Same issue for me.
Vaadin=24.3.3
Spring boot=3.2.2
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 1, got 2. more details logged on DEBUG level.

@ssindelar
Copy link

We have the same issue. It randomly occurs after logging in when opening the first UI after Login.
Vaadin: 24.3.5
Spring boot: 3.2.2

11:38:53.233 DEBUG [http-nio-8090-exec-6] c.v.f.server.communication.ServerRpcHandler:311    - Unexpected message id from the client. Expected sync id: 2, got 3. Message start: 
11:38:53.233 ERROR [http-nio-8090-exec-6] com.vaadin.flow.server.DefaultErrorHandler:105     - 
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 3. more details logged on DEBUG level.

Interestingly the Message Start output ist empty. When debugging I see that the rpcArray is empty which causes the debug output to be empty.
The "changeMessage" is:

{"csrfToken":"40cf2444-6f3f-42a2-bc41-b7df9aa4d1bf","rpc":[],"syncId":2,"clientId":3,"UNLOAD":true}

It just happens on one application and I can't find the difference that causes it.

@SebastianDietrich
Copy link

We have the same issue.

Java: 17
Vaadin: 24.2.9
Spring boot: 3.2.0
Running on google cloud

java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 3. more details logged on DEBUG level.
at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc ( com/vaadin.flow.server.communication/ServerRpcHandler.java:313 )

@difficult2connect
Copy link

Same Issue here, makes the Web basically unusable...
Java: 17
Vaadin: 24.3.7
Spring boot: 3.2.3
Azure Spring Apps

@thomaskiesl
Copy link
Author

Any updates on this? Many of my users are not happy with this situation!?

@mshabarov mshabarov added the bug label Mar 27, 2024
@TatuLund
Copy link
Contributor

That error is actually reported multiple times and has been discussed on many tickets. The error itself is not a bug as is, but logged as part of the failsafe mechanism in Vaadin.

When packets are sent back and forth between server and browser, they include serial number so that both parties can verify that no packet is being lost.

There are natural reasons for packet loss

  • Wrong load balancer / proxy setup, e.g. without sticky sessions
  • Firewall, VPN blocking packet due deep inspection, I have seen cases where packets have been blocked due JavaScript or JSON carried in them and too strict settings
  • The above can also just delay packet arrival, especially virus sniffers are problematic, which may cause problem when WebSocket_XHR is used
  • Faulty router (yes, that has happened in real life, one customer had this and after router firmware update issue disappeared)
  • Flake WiFi/Cellular connection (yes has happened)
  • Bug in Vaadin (we have fixed many, thus most of the tickets discussing this are closed). Naturally this is the final option still which cannot be ruled out.

When communication goes un-sync Vaadin detects that and does resynchronize. That is done on purpose in order to restore the operation.

When you see this error, one should observe does it happen in correlation with some usage pattern of the application, frequency, when it is happening etc. All these can give some hints whether it is due some natural cause of the error.

As you see the list of the natural causes are all flaky, hence deterministic re-production may be difficult.

The cases where it has been a bug in Vaadin have been difficult to debug, but with rigorous attempt of following the statistics, close collaboration with the reporter, ruling out natural causes we have been able to find those and fixed them. Naturally we would like to hope that we have identified all of them, and only the natural causes remain.

@ssindelar
Copy link

I see the error on my development machine from time to time. So I can exclude 1,2,4,5. We actually switched from Sophos to SentinelOne in the mean time so I guess I can also rule out 3.
The only patterns that I see is that is happening when logging in and it is always request 2 that is missing. Everything after this seems fine. But the Logincode and most of the spring security code is located in a shared project and in the other application I wasn't able to reproduce the error.
I will be away for 2 weeks but after that I would love to schedule a meeting, where we could try to find the cause on my machine.

@mshabarov
Copy link
Contributor

Thanks everyone who commented and thanks @ssindelar for the feedback and willing be up for the meeting. This is that I was going to propose: have a video call and investigate the issue together. What I'm afraid of is that this may be not only limited to logging, but to a resync issue in Vaadin that may cause broken UI, e.g. empty page and page load freezing.

Based on the observations, we may need to implement more robust logic for resync and UIDL overall.
I've prioritised this issue for the Vaadin Flow dev team.

Any volunteers are appreciated who can meet with us and show us the problem. Feel free to ping me, e.g. in our Discord (mikhailshabarov) , then we can schedule a meeting.

@jfarjona
Copy link

jfarjona commented Mar 30, 2024

Happening to me too. Running vaadin 24.3.8 on JDK 21, all dependencies for springboot as defined by vaadin-bom.
In my case, it happens if I am using Firefox:

  • I login into the application from a clean browser session
  • I do some actions
  • I logout
  • I try to login again
  • BOOOM.

Only way to login again is by closing the browser and start clean again. I haven't seen this case while using Chrome.

Hope this helps for debugging.

@Legioth
Copy link
Member

Legioth commented Apr 2, 2024

  • I logout
  • I try to login again
  • BOOOM.

This sounds like there's something with the security configuration that causes messages to be eaten after logging in again or maybe that some of the tracking state is not reset.

@guygoldwasser
Copy link

guygoldwasser commented Apr 11, 2024

Same
java 17
vaadin 24.1.10
Azure

seems to be tentative issue

java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 0, got 1. more details logged on DEBUG level.

After investigations base on @TatuLund inputs: Azure WAF was set into prevent mode without filtering unnecessary groups of rules. ~1 of 7 heartbeat calls was rejected, and some of updates calls were rejected too. all of those are false positives of some SQL injection rules.
there is no way to exploits any of those sql injections, and optional solutions are:

  1. Ensure only relevant group of rules are allow.
  2. Change WAF not to be in prevent mode.

from my POV I am happy that app crash due to those blockers on waf, otherwise it would have been even harder to follow other bugs that might come...

@ssindelar
Copy link

Currently it's not happening anymore.

vaadin 24.3.12

@ssindelar
Copy link

ssindelar commented Jun 6, 2024

I think I tracked down the problem. Yesterday in the late afternoon the problem resurfaced with a nearly 100% reproduceability long enough so I could do some debugging before disappearing again a couple of minutes later.

I think the cause of the problem is a request with the "wrong" session id. The expection with the "Unexpected message id from the client" is a result of this but not the cause of the problem. Sadly it couldn't test my findings because it error disappeared so suddenly it reoccured.

What I found:

login requests

The first thing I noticed was that the second request after clicking the Login Button was recieving a session expired response.

for(;;);[{"meta":{"sessionExpired":true}}]

To understand whats happening we need to do a short deep dive into Spring Security and Tomcats session handling.
During the login Spring Security rotates the session id to prevent a Session Fixation Attack. With a couple of tracepoints I was able to see this happening in the ManagerBase classs of Tomcat.

1717652790911: ManagerBase.findSession(): id: ED94756E4B357CE0DB87679830DFD345
1717652790998: ManagerBase.findSession(): id: ED94756E4B357CE0DB87679830DFD345
1717652791138: ManagerBase.rotateSessionId(): IDs ED94756E4B357CE0DB87679830DFD345->B017D99CC310854CB9C3F84C77471FAA
1717652791255: ManagerBase.remove(): ED94756E4B357CE0DB87679830DFD345
1717652791385: ManagerBase.add() id: B017D99CC310854CB9C3F84C77471FAA
1717652791475: ManagerBase.findSession(): id: B017D99CC310854CB9C3F84C77471FAA
1717652791835: ManagerBase.findSession(): id: B017D99CC310854CB9C3F84C77471FAA

When the response of the first request arrives the cookie is updated with the new session id. The second request is send most of the time before the first one returns. So it get's send with the "old" session id. This usually works because the login takes some time and the second request has got the session before the id is changed.

With a breakpoint in ManagerBase.findSession I was able to reproduce the exception by stopping both threads and letting the login update the session id before continueing the second request:

1717665414928: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665415501: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665415576: ManagerBase.rotateSessionId(): IDs 2142A520BADA3B2C14AA8A987FB2E57B->895B54763431012ED472F7BFAD811018
1717665415667: ManagerBase.remove(): 2142A520BADA3B2C14AA8A987FB2E57B
1717665415744: ManagerBase.add() id: 895B54763431012ED472F7BFAD811018
1717665416631: ManagerBase.findSession(): id: 895B54763431012ED472F7BFAD811018
1717665417831: ManagerBase.findSession(): id: 895B54763431012ED472F7BFAD811018
11:16:57.838 ERROR [http-nio-8090-exec-13] com.vaadin.flow.server.DefaultErrorHandler:105     - 
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 3. more details logged on DEBUG level.
	[...]
1717665425751: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665425818: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665425887: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665425959: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665427857: ManagerBase.findSession(): id: 895B54763431012ED472F7BFAD811018
1717665429452: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665429528: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665429601: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B
1717665429672: ManagerBase.findSession(): id: 2142A520BADA3B2C14AA8A987FB2E57B

While it's currently not happening without the breakpoints and manual continuation, I'm very confident I would see a request with the outdated session id that can't find it's session. When a VaadinRequest can't find the session a reconnect is triggered. Now it depends on the timing of the reconnect if the user ends up at the Login or the page after. A reconnect on the page after the login usually goes unnoticed because it looks like a refresh or a little longer load time.

@mcollovati
Copy link
Collaborator

@ssindelar thank you very much for the thorough investigation! This is really helpful!

@ssindelar
Copy link

ssindelar commented Jun 6, 2024

I found a good way to reproduce it. Setting the tomcat max threads to 1 forces a serial processing of the requests and now the second request always gets the sessionExpired:true response.

Spring boot:

server.tomcat.threads.max=1

The bug only occurs when using the vaadin login component.

Session id usage of a "failed" login

1717670183366: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670187420: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670187624: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670187753: ManagerBase.rotateSessionId(): IDs 0BDB1E5F301316D24C23BAEE59CF6390->098A188C5AD6D307166CBB939DE4A586
1717670187902: ManagerBase.remove(): 0BDB1E5F301316D24C23BAEE59CF6390
1717670188044: ManagerBase.add() id: 098A188C5AD6D307166CBB939DE4A586
1717670188138: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670188222: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670188306: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670188385: ManagerBase.findSession(): id: 0BDB1E5F301316D24C23BAEE59CF6390
1717670188473: ManagerBase.findSession(): id: 098A188C5AD6D307166CBB939DE4A586
1717670188589: ManagerBase.findSession(): id: 098A188C5AD6D307166CBB939DE4A586
1717670188785: ManagerBase.findSession(): id: 098A188C5AD6D307166CBB939DE4A586
12:36:28.803 ERROR [http-nio-8092-exec-1] com.vaadin.flow.server.DefaultErrorHandler:105     - 
java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 2, got 3. more details logged on DEBUG level.
	[...]
1717670188872: ManagerBase.findSession(): id: 098A188C5AD6D307166CBB939DE4A586
1717670188967: ManagerBase.findSession(): id: 098A188C5AD6D307166CBB939DE4A586
1717670189037: ManagerBase.findSession(): id: 098A188C5AD6D307166CBB939DE4A586

I'm no Javascript expert but waiting for the first request to finish before sending out the second should fix it.

A possible (bad) workaround would be to make the login slower, so the second request is started after the Session ID is updated. That also explains why we only get the issue on one application because this application has the fastest Login. The others are doing a REST Request to another service for the login.

@SebastianDietrich
Copy link

Shouldn't this bug be moved to github.com/vaadin/vaadin-login/issues ?

@diantonio85
Copy link

Hi, we are also facing this issue randomly.

Forcing Chrome to Low-end mobile profile increases chances to hit the bug.

We are on vaadin 24.3.12

@slawalata
Copy link

Hi, I am facing the same issue. In my case, it always happens during login.
Vaadin 24.4.6 = vaadin LoginForm.
JDK amazoncorretto:21.

It dont appear during local development but when uploaded to cloud, it returns same errors.

many thanks,

@mperktold
Copy link

We also have this issue in production. It's great that finally, there is some way to reproduce it, thanks @ssindelar!

However, I don't think login is the only place where this can happen. We have screenshots of customers where this apparently happens in the middle of a working session.

Therefore, I wonder, what is it that login does "wrong" that leads to this issue?
How can we be sure that our custom components don't make the same mistakes?

@mcollovati
Copy link
Collaborator

An update on the login issue.

The problem seems to be that when you submit the form, Spring Security changes the sessionId, but at the same time the client also sends a UIDL login event with the "old" session cookie.
The UIDL requests then sends back a "Session expired" message, and this could be fine, since we will get a new UI after for submission because of the redirect issued by Spring Security.
However, when the browser is going to be redirected, it also sends an UNLOAD UIDL message with the new session ID, and this is the request that fails because it has clientId=3, but the clientId=2 message was previously rejected because of session expiration.

@timomeinen
Copy link

In my applications, this error appears more often when end user device is mobile Safari on iPad with mobile connections.

@TatuLund
Copy link
Contributor

TatuLund commented Oct 9, 2024

@timomeinen , then you should check this issue instead: #20010

@timomeinen
Copy link

timomeinen commented Oct 9, 2024

Thank you, @TatuLund. I also suspected that the push might be causing the issue, so I disabled @Push in the AppShell since our applications don’t use it (except for the Viritin DynamicDownloadButton, which falls back to polling). However, this didn’t lead to any improvement.

Interestingly, I have a similar application used exclusively by backoffice users on desktop clients, and it doesn’t exhibit these issues.

Note: Our MDM prevents iOS18 until now. So all clients use iOS17.

@jorgheymans
Copy link

jorgheymans commented Oct 11, 2024

Our users are also seeing this sporadically, result is a rather ugly 'invalid json response from server' on the screen. No login form involved, desktop/laptop devices on internal corporate network. Push disabled. Latest 24.4.x

@TatuLund
Copy link
Contributor

@jorgheymans 'invalid json response from server' is not usually related to synchronization as that error is more often related to unexpected closing of the session while client is still running. Then when there is next request, Vaadin does bootstraping and severs the index page, which is naturally a invalid json. This invalid json error can be avoided if there is Vaadin-Refresh token in the content served. Then client will notice this and also restart itself.

@mperktold
Copy link

An update on the login issue...

@mcollovati Your explanation makes sense to me. How does this apply when you invalidate the session manually using VaadinSession.close or WrappedSession.invalidate? We do that in certain situations when we find that the session is not active, and I suspect that in our case, the warnings discussed here come from those rather than login.

Is your draft going to improve things for these situations of things as well?

@mcollovati
Copy link
Collaborator

The draft change on Flow would help in the case of concurrent requests, when one of those invalidates the session and also triggers a redirect. Not sure about your case. If there are no concurrent requests, the cause of the warnings may be different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🔖 High Priority (P1)
Status: 🪵Product backlog
Development

No branches or pull requests