quarkusio/quarkus · error · ErrorDataEncoderException
Header already encoded
Error message
Header already encoded
What it means
finalizeRequest() can only finalize headers once; calling it again after headerFinalized is true throws ErrorDataEncoderException("Header already encoded"). It enforces the encoder's one-shot finalization contract.
Source
Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/PausableHttpPostRequestEncoder.java:812
*/
public HttpRequest finalizeRequest() throws ErrorDataEncoderException {
// Finalize the multipartHttpDatas
if (!headerFinalized) {
if (isMultipart) {
QuarkusInternalAttribute internal = new QuarkusInternalAttribute(charset);
if (duringMixedMode) {
internal.addValue("\r\n--" + multipartMixedBoundary + "--");
}
internal.addValue("\r\n--" + multipartDataBoundary + "--\r\n");
multipartHttpDatas.add(internal);
multipartMixedBoundary = null;
currentFileUpload = null;
duringMixedMode = false;
globalBodySize += internal.size();
}
headerFinalized = true;
} else {
throw new ErrorDataEncoderException("Header already encoded");
}
HttpHeaders headers = request.headers();
List<String> contentTypes = headers.getAll(HttpHeaderNames.CONTENT_TYPE);
if (contentTypes != null) {
headers.remove(HttpHeaderNames.CONTENT_TYPE);
for (String contentType : contentTypes) {
// "multipart/form-data; boundary=--89421926422648"
String lowercased = contentType.toLowerCase();
if (lowercased.startsWith(HttpHeaderValues.MULTIPART_FORM_DATA.toString()) ||
lowercased.startsWith(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED.toString())) {
// ignore
} else {
headers.add(HttpHeaderNames.CONTENT_TYPE, contentType);
}
}
}
if (isMultipart) {View on GitHub (pinned to e1c734241f)
Solutions
- Create a fresh encoder (and re-add body data) for each send/retry
- Guard finalizeRequest with a boolean so it runs once per encoder
- Only call finalizeRequest at the outermost request-building layer
Example fix
// before encoder.finalizeRequest(); // retry path encoder.finalizeRequest(); // throws // after encoder.finalizeRequest(); // retry path PausableHttpPostRequestEncoder encoder2 = new PausableHttpPostRequestEncoder(request, true, charset, factory, mode);
Defensive patterns
Strategy: try-catch
Validate before calling
if (encoder.isFinalized()) { encoder = newEncoderFrom(request, bodyData); } else { encoder.finalizeRequest(); } Type guard
null
Try / catch
try { encoder.finalizeRequest(); } catch (ErrorDataEncoderException e) { /* already finalized: reuse or rebuild */ } Prevention
- Call finalizeRequest exactly once per encoder
- For retries, rebuild encoder and body data from scratch
- Centralize finalization in one code path
When it happens
Trigger: Calling finalizeRequest() twice on the same encoder instance, e.g. on retry or when sending the same request twice.
Common situations: Retry logic that re-invokes finalizeRequest on the original encoder; shared helper methods that each call finalize.
Related errors
- Cannot add value once finalized
- Links context has not been initialized
- Getter accessors container has not been initialized
- setting content of MultiByteHttpData is not supported
- adding content to MultiByteHttpData is not supported
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/340543dc898c3f28.
Report an issue: GitHub.