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

  1. Send a non-empty body from the client (even a space or placeholder) when using text/plain String parameters
  2. Change the resource method to read the raw InputStream or use Optional<String>-style handling if empty bodies are valid
  3. Register a custom ServerMessageBodyReader for String that tolerates empty input
  4. 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

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.