eclipse-vertx/vert.x · error · InputCoercionException

Expected a base64 encoded byte array

Error message

Expected a base64 encoded byte array

What it means

Jackson's BufferDeserializer in Vert.x decodes a JSON string as a Base64-encoded byte array into a io.vertx.core.Buffer. If Base64 decoding fails, the InputCoercionException with 'Expected a base64 encoded byte array' is thrown, aborting deserialization of the JSON document.

Source

Thrown at vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/BufferDeserializer.java:33

import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.deser.std.StdDeserializer;
import io.vertx.core.buffer.Buffer;

import static io.vertx.core.json.impl.JsonUtil.BASE64_DECODER;

class BufferDeserializer extends StdDeserializer<Buffer> {

  BufferDeserializer() {
    super(Buffer.class);
  }

  @Override
  public Buffer deserialize(JsonParser p, DeserializationContext ctxt) {
    String text = p.getString();
    try {
      return Buffer.buffer(BASE64_DECODER.decode(text));
    } catch (IllegalArgumentException e) {
      throw new InputCoercionException(p, "Expected a base64 encoded byte array", p.currentToken(), Buffer.class);
    }
  }
}

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Encode the value as standard Base64 on the producing side (Base64.getEncoder().encodeToString(bytes))
  2. If the data is hex, convert it to Base64 or a byte[] before deserialization, or map the field to a String and decode manually
  3. Pre-validate input strings with Base64.getDecoder().decode() or a regex before feeding them to the mapper

Example fix

// before
{"payload": "deadbeef"}          // hex, not base64
// after
String b64 = java.util.Base64.getEncoder().encodeToString(
    org.vertx.java.core.buffer.impl(hexToBytes("deadbeef")));
{"payload": "3q2+7w=="}          // valid base64
Defensive patterns

Strategy: validation

Validate before calling

private static final java.util.regex.Pattern B64 =
    java.util.regex.Pattern.compile("^[A-Za-z0-9+/]*={0,2}$");
if (value == null || !B64.matcher(value).matches()) {
  throw new IllegalArgumentException("Field must be Base64 encoded");
}

Type guard

boolean isBase64(String s) {
  if (s == null || s.isEmpty()) return false;
  try { java.util.Base64.getDecoder().decode(s); return true; }
  catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
  Buffer b = mapper.readValue(json, MyDto.class).getPayload();
} catch (InputCoercionException e) {
  // log offending token: e.getValue() — value was not Base64
}

Prevention

When it happens

Trigger: Deserializing JSON where a Buffer-typed field holds a value that is not valid Base64 — e.g. a hex string ('0xFF...'), a plain UTF-8 string ('hello world' with spaces), or binary junk produced by a non-Vert.x producer using a different encoding.

Common situations: Cross-language interop where the producer encodes buffers as hex or raw strings instead of Base64; hand-written JSON fixtures with non-Base64 strings; version/codec mismatch between clients writing Dataliner/cluster payloads.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/96651555348e7e45. Report an issue: GitHub.