eclipse-vertx/vert.x · error · InvalidFormatException

Expected a base64 encoded byte array

Error message

Expected a base64 encoded byte array

What it means

ByteArrayDeserializer decodes a JSON string into byte[] via base64. Invalid base64 input makes it throw InvalidFormatException 'Expected a base64 encoded byte array'. Same family as the Buffer deserializer but targeting byte[].

Source

Thrown at vertx-core/src/main/java/io/vertx/core/json/jackson/ByteArrayDeserializer.java:32

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;

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

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

class ByteArrayDeserializer extends JsonDeserializer<byte[]> {

  @Override
  public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    String text = p.getText();
    try {
      return 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. Encode with standard base64 on the producer: Base64.getEncoder().encodeToString(bytes).
  2. Normalize base64url input to standard before sending (char swap + padding).
  3. Check for accidental whitespace/newlines inside the string value.
  4. Map to String and decode manually with a lenient decoder if non-standard encodings must be accepted.

Example fix

// before
{"payload": "a-b_c"} // base64url -> InvalidFormatException
// after
String std = Base64.getUrlDecoder().decode(urlB64) then re-encode;
{"payload": Base64.getEncoder().encodeToString(bytes)}
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Try / catch

try {
  Dto dto = json.mapTo(Dto.class);
} catch (DecodeException e) {
  if (e.getCause() instanceof InvalidFormatException) {
    // locate offending field via ife.getPathReference()
  }
}

Prevention

When it happens

Trigger: JsonObject.mapTo(MyDto.class) or Json.decodeValue(...).mapTo(...) where a byte[]/Byte[] field maps to a JSON string that is not valid standard base64 (URL-safe chars, whitespace, hex, empty garbage).

Common situations: Cross-language producers emitting base64url (Node, Go) consumed by Vert.x expecting standard base64; hand-crafted test fixtures with pseudo-encoded strings; fields holding raw text like 'hello world!' with illegal characters.

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/eca313db746a8bb2. Report an issue: GitHub.