Skip to content

StreamingOutput blocking API does not call reset() on error - clients cannot detect incomplete chunked responses #50754

@jcarranzan

Description

@jcarranzan

Describe the bug

Reviewing and doing a small regression test development coverage for issue #50336 , I've noticed that the fix in PR #50361 only addressed reactive streaming (Multi/Publisher) but did not cover the blocking StreamingOutput API.

Expected behavior

Similar to the fix (PR #50361 )for reactive streams (Multi), when an exception occurs during StreamingOutput streaming:

  • The server should call HttpServerResponse.reset()
  • The final zero-length chunk should NOT be sent
  • HTTP clients should be able to detect the connection was abruptly closed

Actual behavior

When using StreamingOutput with @Blocking, if an exception occurs during streaming:

  • The chunked response is closed normally
  • HTTP clients cannot detect the incomplete transfer

This is the error trace from my test:

2025-10-28 08:20:42,579 ERROR [io.ver.cor.htt.imp.HttpClientRequestImpl] (vert.x-eventloop-thread-1) Connection was closed
08:20:43,588 INFO  [app] 08:20:42,485 HTTP Request to /streaming-output-error?fail=true failed, error id: 253e42d7-48b1-40ab-8b7b-04606bc70b9a-1: java.lang.RuntimeException: java.io.IOException: dummy failure
08:20:43,589 INFO  [app]        at io.quarkus.ts.vertx.StreamingOutputErrorResource.lambda$stream$0(StreamingOutputErrorResource.java:41)
08:20:43,589 INFO  [app]        at org.jboss.resteasy.reactive.server.providers.serialisers.StreamingOutputMessageBodyWriter.writeResponse(StreamingOutputMessageBodyWriter.java:49)
08:20:43,590 INFO  [app]        at org.jboss.resteasy.reactive.server.providers.serialisers.StreamingOutputMessageBodyWriter.writeResponse(StreamingOutputMessageBodyWriter.java:17)
08:20:43,590 INFO  [app]        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:218)
08:20:43,591 INFO  [app]        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:186)
08:20:43,591 INFO  [app]        at org.jboss.resteasy.reactive.server.core.serialization.FixedEntityWriterArray.write(FixedEntityWriterArray.java:31)
08:20:43,592 INFO  [app]        at org.jboss.resteasy.reactive.server.handlers.ResponseWriterHandler.handle(ResponseWriterHandler.java:34)
08:20:43,593 INFO  [app]        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:189)
08:20:43,593 INFO  [app]        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
08:20:43,593 INFO  [app]        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:645)
08:20:43,594 INFO  [app]        at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2651)
08:20:43,594 INFO  [app]        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2630)
08:20:43,595 INFO  [app]        at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1622)
08:20:43,595 INFO  [app]        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1589)
08:20:43,596 INFO  [app]        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
08:20:43,596 INFO  [app]        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
08:20:43,597 INFO  [app]        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
08:20:43,597 INFO  [app]        at java.base/java.lang.Thread.run(Thread.java:1583)
08:20:43,598 INFO  [app] Caused by: java.io.IOException: dummy failure
08:20:43,598 INFO  [app]        at io.quarkus.ts.vertx.StreamingOutputErrorResource.lambda$stream$0(StreamingOutputErrorResource.java:35)
08:20:43,599 INFO  [app]        ... 17 more
08:20:43,599 INFO  [app] 08:20:42,543 Exception in SSE server handling, impossible to send it to client: io.vertx.core.impl.NoStackTraceException: dummy failure
08:20:44,700 INFO  [app] Service stopped (Quarkus JVM mode)
[ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 6.077 s <<< FAILURE! -- in io.quarkus.ts.vertx.StreamingErrorIT
[ERROR] io.quarkus.ts.vertx.StreamingErrorIT.testStreamingOutputFailureMidStream -- Time elapsed: 0.022 s <<< FAILURE!
org.opentest4j.AssertionFailedError: Client should have failed as the server reset the connection (StreamingOutput) ==> Expected java.util.concurrent.ExecutionException to be thrown, but nothing was thrown.
        at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
        at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:73)
        at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:39)
        at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3153)
        at io.quarkus.ts.vertx.StreamingErrorIT.lambda$testStreamingOutputFailureMidStream$9(StreamingErrorIT.java:114)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1583)

[INFO] 
[INFO] Results:
[INFO] 
[ERROR] Failures: 
[ERROR]   StreamingErrorIT.lambda$testStreamingOutputFailureMidStream$9:114 Client should have failed as the server reset the connection (StreamingOutput) ==> Expected java.util.concurrent.ExecutionException to be thrown, but nothing was thrown.
[INFO] 

How to Reproduce?

Go to my branch https://github.com/jcarranzan/quarkus-test-suite/blob/test-development/chunked-response-issue-50336/http/vertx/src/test/java/io/quarkus/ts/vertx/StreamingErrorIT.java here and execute the test testStreamingOutputFailureMidStream

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

No response

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions