quarkusio/quarkus · warning · BadRequestException
Bad Request
Error message
Bad Request
What it means
The default String body reader for text/plain input rejects an empty request body: ServerDefaultTextPlainBodyHandler.validateInput throws BadRequestException with an empty entity so the HTTP 400 response is returned as-is. Reading a String parameter from a request with no body is treated as a client error rather than producing null.
Source
Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/providers/serialisers/ServerDefaultTextPlainBodyHandler.java:26
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.jboss.resteasy.reactive.common.providers.serialisers.DefaultTextPlainBodyHandler;
import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyReader;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;
@Consumes("text/plain")
public class ServerDefaultTextPlainBodyHandler extends DefaultTextPlainBodyHandler implements ServerMessageBodyReader<Object> {
@Override
protected void validateInput(String input) throws ProcessingException {
if (input.isEmpty()) {
// add an empty, non-null entity in order to ensure that the response will be used as is
// TODO: this seems to be an edge case, but perhaps it needs to be handled by RequestDeserializeHandler?
throw new BadRequestException(Response.status(Response.Status.BAD_REQUEST).entity("").build());
}
}
@Override
public boolean isReadable(Class<?> type, Type genericType, ResteasyReactiveResourceInfo lazyMethod,
MediaType mediaType) {
return super.isReadable(type, genericType, null, mediaType);
}
@Override
public Object readFrom(Class<Object> type, Type genericType, MediaType mediaType, ServerRequestContext context)
throws WebApplicationException, IOException {
return doReadFrom(type, mediaType, context.getInputStream());
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Send a non-empty body from the client (even a space or placeholder) when using text/plain String parameters
- Change the resource method to read the raw InputStream or use Optional<String>-style handling if empty bodies are valid
- Register a custom ServerMessageBodyReader for String that tolerates empty input
- Use a different content type/handler (e.g. JSON with a default) when empty bodies should map to null
Example fix
// before (client) curl -X POST http://localhost:8080/echo // empty body -> 400 // after curl -X POST -H "Content-Type: text/plain" -d "hello" http://localhost:8080/echo
Defensive patterns
Strategy: validation
Validate before calling
// client-side: ensure the text/plain body is non-empty before POSTing
if (body == null || body.isEmpty()) {
throw new IllegalArgumentException("text/plain endpoints reject an empty body");
} Try / catch
try {
return client.post(body);
} catch (BadRequestException e) {
// 400 from empty text/plain body
return sendWithPlaceholderOrSkip(e);
} Prevention
- Send a non-empty body when the endpoint consumes text/plain
- Prefer reading InputStream or Optional-based handling when empty bodies are legitimate
- Document the empty-body behavior in the endpoint contract
- Set Content-Type explicitly so the right body handler runs
When it happens
Trigger: A resource method taking a plain String (or text/plain) body parameter while the client sends an empty request body (Content-Length: 0 or empty streamed input) — validateInput receives input.isEmpty() == true.
Common situations: Clients posting with no body to endpoints expecting text/plain payloads; curl commands without -d; empty form fields mapped to String body; tests sending empty POST bodies.
Related errors
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/255b93bdcf2e553f.
Report an issue: GitHub.