{"record":{"id":"4c7aed48114fafbd","repo":"quarkusio/quarkus","slug":"entity-stream-has-already-been-read-and-is-not-buf","errorCode":null,"errorMessage":"Entity stream has already been read and is not buffered: call Response.bufferEntity()","messagePattern":"Entity stream has already been read and is not buffered: call Response\\.bufferEntity\\(\\)","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientRestResponseImpl.java","lineNumber":45,"sourceCode":"            return (OtherT) entity;\n        }\n\n        checkClosed();\n\n        // apparently we're trying to re-read it here, even if we already have an entity, as long as it's not the right\n        // type\n        // Note that this will get us the entity if it's an InputStream because setEntity checks that\n        InputStream entityStream = getEntityStream();\n        if (entityStream == null) {\n            entityStream = new EmptyInputStream();\n        }\n\n        // it's possible we already read it for a different type, so try to reset it\n        try {\n            if (buffered) {\n                entityStream.reset();\n            } else if (consumed) {\n                throw new IllegalStateException(\n                        \"Entity stream has already been read and is not buffered: call Response.bufferEntity()\");\n            }\n        } catch (IOException e) {\n            throw new ProcessingException(e);\n        }\n\n        // Spec says to return the input stream as-is, without closing it, if that's what we want\n        if (InputStream.class.isAssignableFrom(entityType)) {\n            return (OtherT) entityStream;\n        }\n\n        MediaType mediaType = getMediaType();\n        try {\n            entity = (T) ClientSerialisers.invokeClientReader(annotations, entityType, genericType, mediaType,\n                    restClientRequestContext.properties, restClientRequestContext, getStringHeaders(),\n                    restClientRequestContext.getRestClient().getClientContext().getSerialisers(),\n                    entityStream, restClientRequestContext.getReaderInterceptors(), restClientRequestContext.configuration);\n            consumed = true;","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientRestResponseImpl.java#L27-L63","documentation":"The response entity stream was already fully consumed by an earlier readEntity() call, and because bufferEntity() was never called the stream cannot be rewound. ClientRestResponseImpl.readEntity() tries entityStream.reset() only when `buffered` is true; when `consumed` is true it throws this IllegalStateException telling you to call bufferEntity() first.","triggerScenarios":"Calling readEntity() (or readEntity with a different type) twice on the same Response without calling bufferEntity() before the first read.","commonSituations":"Logging the entity as String then parsing it as a DTO; interceptor/filter reads the body and application code reads it again; retry/deserialization logic re-reading the entity on error paths; generic wrapper code reading the entity for type checks then delegating.","solutions":["Call response.bufferEntity() once before the first readEntity(); subsequent readEntity calls will then succeed with any compatible type","If you only need the value once, read it a single time into the final type and reuse that object","Read the entity as InputStream only if you handle buffering/rewinding yourself","Restructure interceptors so they do not consume the entity stream, or have them buffer it"],"exampleFix":"// before\nString raw = res.readEntity(String.class);\nMyDto dto = res.readEntity(MyDto.class); // IllegalStateException\n\n// after\nres.bufferEntity();\nString raw = res.readEntity(String.class);\nMyDto dto = res.readEntity(MyDto.class); // OK: stream was buffered and reset","handlingStrategy":"try-catch","validationCode":"// buffer before any repeated read\nif (!response.bufferEntity()) { /* entity absent or already streaming-only */ }\nMyDto dto = response.readEntity(MyDto.class);","typeGuard":null,"tryCatchPattern":"try {\n    return response.readEntity(MyDto.class);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Entity stream has already been read\")) {\n        throw new IllegalStateException(\"Call response.bufferEntity() before the first readEntity()\", e);\n    }\n    throw e;\n}","preventionTips":["Call bufferEntity() before the first readEntity() whenever the entity may be read more than once","Read the entity exactly once into the final type when buffering is not desired","Ensure filters/interceptors do not consume the entity stream before application code","Never mix raw InputStream reads with subsequent readEntity() calls unless you buffer"],"tags":["rest-client","stream","entity","lifecycle"],"backgroundTag":"entity-stream-already-consumed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}