quarkusio/quarkus · error · BuildException

Extra steps left over

Error message

Extra steps left over

What it means

RootResource.posts (POST, text/plain) throws "No post data" when the JAX-RS request entity resolves to null. This happens when the POST body is absent, empty, or has a Content-Type inconsistent with @Consumes(TEXT_PLAIN), so the String parameter is never populated.

Source

Thrown at core/builder/src/main/java/io/quarkus/builder/Execution.java:149

                intr = true;
            } finally {
                if (intr)
                    Thread.currentThread().interrupt();
            }
        for (Diagnostic diagnostic : diagnostics) {
            if (diagnostic.getLevel() == Diagnostic.Level.ERROR) {
                BuildException failed = new BuildException("Build failed due to errors", diagnostic.getThrown(),
                        Collections.unmodifiableList(diagnostics));
                for (Diagnostic i : diagnostics) {
                    if (i.getThrown() != null && i.getThrown() != diagnostic.getThrown()) {
                        failed.addSuppressed(i.getThrown());
                    }
                }
                throw failed;
            }
        }
        if (lastStepCount.get() > 0)
            throw new BuildException("Extra steps left over", Collections.emptyList());

        long duration = max(0, System.nanoTime() - start);
        metrics.buildFinished(TimeUnit.NANOSECONDS.toMillis(duration));
        return new BuildResult(singles, multis, finalIds, Collections.unmodifiableList(diagnostics),
                duration, metrics, chain.getClassLoader());
    }

    EnhancedQueueExecutor getExecutor() {
        return executor;
    }

    String getBuildTargetName() {
        return buildTargetName;
    }

    void setErrorReported() {
        errorReported.compareAndSet(false, true);
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Send a non-empty text/plain body with the POST request (e.g. curl -H 'Content-Type: text/plain' -d 'payload' ...).
  2. Ensure the Content-Type header is text/plain to match @Consumes.
  3. Null-check data before use and return 400 instead of RuntimeException.
  4. Verify no filter/proxy removes the request body.

Example fix

// before
public String posts(String data, @Context SecurityContext sec) {
    if (data == null) {
        throw new RuntimeException("No post data");
    }
// after
curl -H "Content-Type: text/plain" -d "hello" http://localhost:8080/
// and/or in code: return Response.status(400).build() when data == null
Defensive patterns

Strategy: validation

Validate before calling

if (fruit.getId() != null) {
    fruit = new Fruit(fruit.getName()); // drop id before POST
}
given().contentType(ContentType.JSON).body(fruit).post("/fruits");

Type guard

static Fruit withoutId(Fruit f) {
    return f.getId() == null ? f : new Fruit(f.getName());
}

Try / catch

try {
    given().body(fruit).post("/fruits");
} catch (WebApplicationException e) {
    if (e.getResponse().getStatus() == 422) { fruit.setId(null); /* retry POST */ }
    else throw e;
}

Prevention

When it happens

Trigger: POST to the resource with an empty body, no body at all, or a Content-Type other than text/plain (e.g. none or application/json), causing data == null.

Common situations: Test client sending POST without a body; curl forgetting -d or -H 'Content-Type: text/plain'; framework/quarkus-rest clients serializing nothing; gateway stripping the body.

Related errors


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