eclipse-vertx/vert.x · error · InputCoercionException

Expected a base64 encoded byte array

Error message

Expected a base64 encoded byte array

What it means

Jackson deserializer for byte[] fields (io.vertx.core.json.jackson.v3.ByteArrayDeserializer) tries to Base64-decode the current JSON string token. If Base64 decoding fails with IllegalArgumentException, it wraps it in an InputCoercionException with the message 'Expected a base64 encoded byte array'. This happens because Vert.x JSON encodes byte arrays as Base64 strings, so any non-Base64 text in a byte[] field is rejected.

Source

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

import tools.jackson.core.exc.InputCoercionException;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.deser.std.StdDeserializer;

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

class ByteArrayDeserializer extends StdDeserializer<byte[]> {

  ByteArrayDeserializer() {
    super(byte[].class);
  }

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

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Fix the producer to emit standard Base64: Base64.getEncoder().encodeToString(bytes).
  2. If the source is URL-safe Base64, normalize it first (replace '-' with '+' and '_' with '/') before decoding, or configure a deserializer that uses Base64.getUrlDecoder().
  3. Strip whitespace/newlines from the string; java.util.Base64 rejects any character outside the alphabet.
  4. If the value is actually hex or plain text, change the target field type to String and decode manually.

Example fix

// before
{"data": "68656c6c6f"} // hex string in byte[] field
// after
{"data": "aGVsbG8="} // standard Base64
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

if (raw instanceof String s && isStandardBase64(s)) { byte[] data = Base64.getDecoder().decode(s); }

Try / catch

try {
  byte[] data = Base64.getDecoder().decode(text);
} catch (IllegalArgumentException e) {
  throw new IllegalArgumentException("Field 'data' is not standard Base64: " + text, e);
}

Prevention

When it happens

Trigger: Decoding JSON where a field mapped to byte[] (or JsonObject binary values) contains a string that is not valid Base64, e.g. '{"data":"not-base64!!"}' passed to Json.decodeValue(..., MyType.class) or ObjectMapper.readValue.

Common situations: Hand-written JSON/config files where binary data was pasted as hex, raw text, or Base64 with whitespace/URL-safe alphabet ('-','_') while the decoder expects the standard alphabet; clients sending base16-encoded keys or certificates instead of Base64.

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