Skip to content

Provide configuration properties for controlling the size of Tomcat's buffers for binary and text WebSocket messages #47944

@mohan-ganesh

Description

@mohan-ganesh

When using Spring Boot with STOMP over WebSockets, applications can easily encounter a CloseStatus[code=1009] error when a client sends a message that exceeds the default buffer size. This is a common scenario in applications that transmit data like Base64-encoded audio, images, or large JSON payloads.

The root cause is that the embedded Tomcat's default WebSocket message buffer size is set to a very low 8192 bytes (8KB). This default is defined in Tomcat's internal constants and there is no override properties available for user to change this value: https://github.com/apache/tomcat/blob/c4c733a4e2dd65fab42434b81339f6ba13ed7301/java/org/apache/tomcat/websocket/Constants.java#L43

When a message exceeds this limit, the connection is abruptly closed with the following log message, which can be confusing to debug:

o.s.w.s.h.LoggingWebSocketHandlerDecorator : StandardWebSocketSession[...] closed with CloseStatus[code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages]

in a normal circumstances you dont even see this log unless you add the additional properties

logging.level.org.springframework.web.socket=DEBUG
logging.level.org.springframework.messaging.simp=DEBUG 

Why This is a Spring Boot Issue
The developer experience for resolving this is not ideal. A developer's first instinct is to configure Spring's own properties, such as:

# This only configures the STOMP message size, not the underlying transport buffer
spring.websocket.messaging.stomp.message-size-limit=512000

However, this property alone is insufficient because it does not affect the underlying Tomcat transport layer's buffer size. To properly solve this, one must dive deep into container-specific configuration by implementing a WebServerFactoryCustomizer, as shown in the reproduction project. This involves casting to a TomcatServletWebServerFactory and accessing the internal WsServerContainer to override the buffer sizes.

This feels like a leaky abstraction. A common requirement like increasing the WebSocket message size should ideally be managed through straightforward properties provided by Spring Boot, abstracting away the specifics of the underlying servlet container (be it Tomcat, Jetty, or Undertow).

How to Reproduce the Issue
I have created a sample project that demonstrates the problem and includes a workaround that can be toggled on or off.

Repository: https://github.com/mohan-ganesh/tts-services

Steps to Reproduce:

  1. Clone the repository: git clone https://github.com/mohan-ganesh/tts-services.git

  2. Navigate to the project directory.

  3. Open src/main/resources/application.properties and ensure the workaround is disabled by setting the following property to false:

  4. Run the Spring Boot application: ./mvnw spring-boot:run

  5. Open a web browser and go to http://localhost:8080.

  6. Click the "Connect" button to establish a WebSocket connection.

  7. Click "Start Recording", speak for 5-10 seconds to generate a sufficiently large audio payload, and then click "Stop and Send".

  8. Observe the server logs. The application will log a CloseStatus[code=1009] error, and the client will disconnect.

To see the fix in action, you can change server.tomcat.max-websocket-message-size.override back to true and restart the application. The larger message will then be processed successfully.

Suggested Solution
It would significantly improve the developer experience if Spring Boot provided first-class properties to configure the underlying WebSocket message size limits for embedded servers.

First i wanted to check to see community response on this issue and based on the work around that is being done how that can be implemented in sprint-boot framework.

please let me know if you need additional details on recreating the problem or any additional details that would be required..

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions