Skip to content

PerConnectionWebSocketHandler must not refuse handleTransportError #37626

Open

Description

@michaldo

PerConnectionWebSocketHandler assumes that afterConnectionClosed() handleTransportError() is never called

It is not true.
I typed websocat ws://localhost:8080, waited enough time and pressed CTRC-C

I saw in logs:

2026-11-01T13:45:50.986+01:00  INFO 34584 --- [WebSocket background processing] demo : Session ae1bae4b removed CloseStatus[code=1006, reason=The WebSocket session [0] idle timeout expired]
2026-11-01T13:45:54.800+01:00 ERROR 34584 --- [http-nio-8080-exec-8] w.s.h.ExceptionWebSocketHandlerDecorator : Closing session due to exception for StandardWebSocketSession[id=ae1bae4b-1711-4427-bb42-a34fce2eb5dd, uri=ws://localhost:8080/]

java.lang.IllegalStateException: WebSocketHandler not found for StandardWebSocketSession[id=ae1bae4b-1711-4427-bb42-a34fce2eb5dd, uri=ws://localhost:8080/]
	at org.springframework.web.socket.handler.PerConnectionWebSocketHandler.getHandler(PerConnectionWebSocketHandler.java:113) ~[spring-websocket-7.0.10.jar:7.0.10]
	at org.springframework.web.socket.handler.PerConnectionWebSocketHandler.handleTransportError(PerConnectionWebSocketHandler.java:91) ~[spring-websocket-7.0.10.jar:7.0.10]
	at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleTransportError

I do not know what is expected behavior.
Undoubtedly, Tomcat is not illegal. An instinctive reaction is ignore the error, but someone may say that it must be customisable

spring-websocket-7.0.10

Activity

  1. michaldo commented on Nov 1, 2026

    @michaldo
    Author

    I provoked the error with the following setup:

        System.setProperty(
             "org.apache.tomcat.websocket.DEFAULT_PROCESS_PERIOD",
             "1"
          );
    
       @Bean
       public ServletServerContainerFactoryBean createWebSocketContainer() {
          ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
          container.setMaxSessionIdleTimeout(2000L);
          return container;
       }
    
  2. ratnaaaaaaa commented on Nov 2, 2026

    @ratnaaaaaaa

    Hi! I'm interested in contributing to this issue.

    I've been looking into the PerConnectionWebSocketHandler lifecycle and the reported behaviour where handleTransportError() attempts to retrieve a handler after the connection has already been removed.

    Before starting an implementation, I'd like to clarify the expected behaviour. Should transport errors received after connection cleanup be safely ignored, or should the handler support another form of error handling in this situation?

    I'd be happy to investigate the issue, add regression tests, and submit a fix once the intended behaviour is clear.

    Thank you!

  3. michaldo commented on Nov 2, 2026

    @michaldo
    Author

    5.1. Threading Considerations
    Implementations of the WebSocket API may employ a variety of threading strategies in order to provide a scalable implementation. The specification aims to allow a range of strategies. However, the implementation must fulfill certain threading requirements in order to provide the developer a consistent threading environment for their applications.

    PerConnectionWebSocketHandler appears to be built on the assumption that afterConnectionClosed() is the final callback for a given connection, whereas the specification clearly states otherwise.

    This means that the entire concept behind PerConnectionWebSocketHandler is built on a flawed assumption.

    In my opinion, PerConnectionWebSocketHandler cannot be fixed without introducing sophisticated lifecycle management logic that would be difficult for maintainers to maintain and difficult for developers to understand and use correctly.

    I also believe that PerConnectionWebSocketHandler provides very little value, as its functionality can be easily replaced with a regular handler backed by a ConcurrentHashMap.

    Furthermore, when the individual handlers managed by PerConnectionWebSocketHandler are Spring beans, it is unclear which Spring bean features, beyond constructor injection, are actually available to them.

    Taking all of this into account, I believe that PerConnectionWebSocketHandler is a dead end and should be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions