quarkusio/quarkus · error · IllegalStateException

Reading MultiByteHttpData as String is not supported

Error message

Reading MultiByteHttpData as String is not supported

What it means

getString() decodes the whole part content into a String in standard Netty HttpData. MultiByteHttpData is a streaming adapter that cannot (and must not) materialize all bytes into a String, so it always throws IllegalStateException. This is an intentional unsupported-operation guard, not a state error.

Source

Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/MultiByteHttpData.java:221

        ByteBuf result = VertxByteBufAllocator.DEFAULT.heapBuffer(toRead, toRead);

        // finish if the whole buffer is filled
        // or we hit the end, `done` && buffer.readableBytes == 0
        while (toRead > 0 && !(buffer.readableBytes() == 0 && done)) {
            int readBytes = Math.min(buffer.readableBytes(), toRead);
            result.writeBytes(buffer.readBytes(readBytes));
            buffer.discardReadBytes();
            subscription.request(readBytes);

            toRead -= readBytes;
        }
        return result;
    }

    @Override
    public String getString() {
        throw new IllegalStateException("Reading MultiByteHttpData as String is not supported");
    }

    @Override
    public String getString(Charset encoding) {
        throw new IllegalStateException("Reading MultiByteHttpData as String is not supported");
    }

    @Override
    public boolean renameTo(File dest) {
        throw new IllegalStateException("Renaming destination file for MultiByteHttpData is not supported");
    }

    @Override
    public boolean isInMemory() {
        return true;
    }

    @Override

View on GitHub (pinned to e1c734241f)

Solutions

  1. Read content incrementally via getChunk(int) after isReady(...) and decode chunks yourself if you truly need text.
  2. If the body is textual, send a String part instead of a Multi<Byte> streaming part.
  3. Collect the source Multi<Byte> upstream and decode from the collected bytes, not from the adapter.
  4. Branch on concrete type before calling getString on InterfaceHttpData instances.

Example fix

// before
String text = httpData.getString();
// after
if (httpData instanceof MultiByteHttpData) {
    // read via getChunk after isReady, decode chunk by chunk
} else {
    String text = httpData.getString();
}
Defensive patterns

Strategy: type-guard

Validate before calling

String safeGetString(InterfaceHttpData data) {
    if (data instanceof MultiByteHttpData) {
        throw new IllegalArgumentException("Read streaming parts via getChunk(); getString is unsupported");
    }
    return data.getString();
}

Type guard

boolean supportsString(InterfaceHttpData data) {
    return !(data instanceof MultiByteHttpData);
}

Try / catch

try {
    String s = data.getString();
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("not supported")) {
        // decode incrementally from getChunk() instead
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling getString() on a MultiByteHttpData - typically from logging, debugging, or generic InterfaceHttpData iteration code that stringifies every part of a multipart request/response.

Common situations: Printing multipart parts for diagnostics (including MultiByteHttpData.toString users who then call getString); generic form-data decoders on the server or on response handling; test assertions that read part content as text.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/1a7036dc4927bfae. Report an issue: GitHub.