quarkusio/quarkus · error · IllegalStateException
getContent() has already been invoked
Error message
getContent() has already been invoked
What it means
EntityPartImpl.getContent() (the InputStream overload) throws IllegalStateException if called more than once. An EntityPart's body is a one-shot stream; once consumed it cannot be rewound, so the implementation guards with a compareAndSet flag and fails fast on the second call. This mirrors the JAX-RS 3.1 spec's single-consumption semantics.
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/EntityPartImpl.java:56
this.mediaType = mediaType;
this.content = content;
this.serialisers = serialisers;
}
@Override
public String getName() {
return name;
}
@Override
public Optional<String> getFileName() {
return Optional.ofNullable(fileName);
}
@Override
public InputStream getContent() {
if (!contentConsumed.compareAndSet(false, true)) {
throw new IllegalStateException("getContent() has already been invoked");
}
return content;
}
@Override
public <T> T getContent(Class<T> type)
throws IllegalArgumentException, IllegalStateException, IOException, WebApplicationException {
if (!contentConsumed.compareAndSet(false, true)) {
throw new IllegalStateException("getContent() has already been invoked");
}
return readContent(type, type);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getContent(GenericType<T> type)
throws IllegalArgumentException, IllegalStateException, IOException, WebApplicationException {
if (!contentConsumed.compareAndSet(false, true)) {View on GitHub (pinned to e1c734241f)
Solutions
- Call getContent() exactly once and buffer the bytes (read all into byte[]) if you need multiple uses.
- Use one of the typed overloads getContent(Class) / getContent(GenericType) instead of multiple raw reads.
- Cache the converted value (e.g. String or byte[]) in a local variable and reuse it.
Example fix
// before String logged = new String(part.getContent().readAllBytes()); process(part.getContent()); // IllegalStateException: already invoked // after byte[] data = part.getContent().readAllBytes(); String logged = new String(data); process(new ByteArrayInputStream(data));
Defensive patterns
Strategy: try-catch
Try / catch
try {
InputStream in = part.getContent();
byte[] data = in.readAllBytes(); // consume once, reuse everywhere
} catch (IllegalStateException e) {
if (e.getMessage().contains("already been invoked")) {
throw new IllegalStateException("part content read twice; buffer instead", e);
}
throw e;
} Prevention
- Read multipart part content exactly once and buffer bytes for reuse.
- Never pass the raw EntityPart to multiple consumers; pass the buffered data.
- Avoid reading content in interceptors/logging before business code.
When it happens
Trigger: Calling part.getContent() twice on the same EntityPart obtained from a MultipartFormDataOutput response or client parse — e.g. reading the raw stream and then, in error handling or logging, reading it again.
Common situations: Logging part content then passing it downstream; retry/error paths that re-read the same part; interceptors or filters that consume the content before the business code does.
Related errors
- No content has been set
- quarkus.rest.client.multipart-buffer-size cannot be lower th
- setting content of MultiByteHttpData is not supported
- adding content to MultiByteHttpData is not supported
- getting all the contents of a MultiByteHttpData is not suppo
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d8b54bc7d693dd8d.
Report an issue: GitHub.