eclipse-vertx/vert.x · error · InvalidFormatException

Expected a base64 encoded byte array

Error message

Expected a base64 encoded byte array

What it means

BufferDeserializer decodes a JSON string into a Vert.x Buffer by base64-decoding it. When the string is not valid base64 (or uses an incompatible alphabet/padding), it throws InvalidFormatException with 'Expected a base64 encoded byte array'.

Source

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

import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import io.vertx.core.buffer.Buffer;

import java.io.IOException;
import java.time.Instant;

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

class BufferDeserializer extends JsonDeserializer<Buffer> {

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

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Base64-encode the data on the producer side using the standard (RFC 4648) alphabet: Base64.getEncoder().encodeToString(bytes).
  2. If the input is base64url, convert it: replace '-' with '+', '_' with '/', and pad with '=' to a multiple of 4.
  3. If the field is actually hex, decode hex first then re-encode as base64.
  4. If the field should stay text, change the target type from Buffer to String.

Example fix

// before
{"data": "deadbeef"} // InvalidFormatException
// after
String b64 = Base64.getEncoder().encodeToString(Hex.decodeHex("deadbeef"));
{"data": b64}
Defensive patterns

Strategy: validation

Validate before calling

String data = json.getString("data");
if (data != null && !data.matches("[A-Za-z0-9+/]*={0,2}")) throw new IllegalArgumentException("data is not standard base64");

Type guard

static boolean isStandardBase64(String s) {
  return s != null && s.matches("[A-Za-z0-9+/]+={0,2}") && s.length() % 4 == 0;
}

Try / catch

try {
  Config cfg = Json.decodeValue(body, Config.class);
} catch (DecodeException e) {
  if (e.getCause() instanceof InvalidFormatException ife && "Expected a base64 encoded byte array".equals(ife.getOriginalMessage())) {
    // handle bad base64 field
  }
}

Prevention

When it happens

Trigger: Databind deserialization (JsonObject.mapTo / DatabindCodec.from* ) mapping a JSON field to io.vertx.core.Buffer where the field value is not valid standard base64, e.g. contains whitespace, URL-safe characters (-, _), hex, or raw binary text.

Common situations: A producer encoded the buffer as base64url while the deserializer expects standard base64; the JSON field holds a hex string like 'deadbeef'; the field is a plain string payload that was never base64-encoded at all.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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