elastic/elasticsearch · error · UnsupportedOperationException

{} with body is not supported

Error message

{} with body is not supported

What it means

Thrown by addRequestBody when a request body/entity is supplied for an HTTP method whose request type is not HttpEntityEnclosingRequestBase (i.e. not POST/PUT/PATCH/OPTIONS/TRACE). Those verbs (GET, DELETE, HEAD) never carry a body in Apache HttpClient, so the client refuses to attach one.

Source

Thrown at client/rest/src/main/java/org/elasticsearch/client/RestClient.java:632

                return httpPost;
            case HttpPut.METHOD_NAME:
                return addRequestBody(new HttpPut(uri), entity, compressionEnabled);
            case HttpTrace.METHOD_NAME:
                return addRequestBody(new HttpTrace(uri), entity, compressionEnabled);
            default:
                throw new UnsupportedOperationException("http method not supported: " + method);
        }
    }

    private static HttpRequestBase addRequestBody(HttpRequestBase httpRequest, HttpEntity entity, boolean compressionEnabled) {
        if (entity != null) {
            if (httpRequest instanceof HttpEntityEnclosingRequestBase) {
                if (compressionEnabled) {
                    entity = new ContentCompressingEntity(entity);
                }
                ((HttpEntityEnclosingRequestBase) httpRequest).setEntity(entity);
            } else {
                throw new UnsupportedOperationException(httpRequest.getMethod() + " with body is not supported");
            }
        }
        return httpRequest;
    }

    static URI buildUri(String pathPrefix, String path, Map<String, String> params) {
        Objects.requireNonNull(path, "path must not be null");
        try {
            String fullPath;
            if (pathPrefix != null && pathPrefix.isEmpty() == false) {
                if (pathPrefix.endsWith("/") && path.startsWith("/")) {
                    fullPath = pathPrefix.substring(0, pathPrefix.length() - 1) + path;
                } else if (pathPrefix.endsWith("/") || path.startsWith("/")) {
                    fullPath = pathPrefix + path;
                } else {
                    fullPath = pathPrefix + "/" + path;
                }
            } else {

View on GitHub (pinned to db6a809a66)

Solutions

  1. For GET/HEAD/DELETE, move parameters into the query string or endpoint path instead of a body.
  2. If you genuinely need a body, switch the method to POST (e.g. use POST _search with the query body).
  3. Audit request.setEntity / Request.setJsonEntity calls adjacent to GET/DELETE/HEAD constructors.

Example fix

// before
Request req = new Request("GET", "/index/_search");
req.setJsonEntity("{\"query\":{\"match_all\":{}}}");
// after
Request req = new Request("POST", "/index/_search");
req.setJsonEntity("{\"query\":{\"match_all\":{}}}");
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> BODY_OK = Set.of("POST","PUT","PATCH","OPTIONS","TRACE");
if (entity != null && !BODY_OK.contains(method)) throw new IllegalArgumentException(method + " must not carry a body");
Request req = new Request(method, endpoint);
if (entity != null) req.setJsonEntity(entity);

Prevention

When it happens

Trigger: Calling request.setEntity(...) or building a Request with a JSON body for a GET, DELETE or HEAD. Also reached indirectly via low-level helpers that always pass an entity.

Common situations: Sending a GET with a body (some APIs allow it, Elasticsearch generally does not); DELETE-with-body patterns ported from other HTTP clients; mistakenly attaching a body to a HEAD index-exists request.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/0b37babfdf17cf89. Report an issue: GitHub.