{"record":{"id":"96651555348e7e45","repo":"eclipse-vertx/vert.x","slug":"expected-a-base64-encoded-byte-array-966515","errorCode":null,"errorMessage":"Expected a base64 encoded byte array","messagePattern":"Expected a base64 encoded byte array","errorType":"exception","errorClass":"InputCoercionException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/BufferDeserializer.java","lineNumber":33,"sourceCode":"import tools.jackson.databind.DeserializationContext;\nimport tools.jackson.databind.deser.std.StdDeserializer;\nimport io.vertx.core.buffer.Buffer;\n\nimport static io.vertx.core.json.impl.JsonUtil.BASE64_DECODER;\n\nclass BufferDeserializer extends StdDeserializer<Buffer> {\n\n  BufferDeserializer() {\n    super(Buffer.class);\n  }\n\n  @Override\n  public Buffer deserialize(JsonParser p, DeserializationContext ctxt) {\n    String text = p.getString();\n    try {\n      return Buffer.buffer(BASE64_DECODER.decode(text));\n    } catch (IllegalArgumentException e) {\n      throw new InputCoercionException(p, \"Expected a base64 encoded byte array\", p.currentToken(), Buffer.class);\n    }\n  }\n}\n","sourceCodeStart":15,"sourceCodeEnd":37,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/BufferDeserializer.java#L15-L37","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Encode the value as standard Base64 on the producing side (Base64.getEncoder().encodeToString(bytes))","If the data is hex, convert it to Base64 or a byte[] before deserialization, or map the field to a String and decode manually","Pre-validate input strings with Base64.getDecoder().decode() or a regex before feeding them to the mapper"],"exampleFix":"// before\n{\"payload\": \"deadbeef\"}          // hex, not base64\n// after\nString b64 = java.util.Base64.getEncoder().encodeToString(\n    org.vertx.java.core.buffer.impl(hexToBytes(\"deadbeef\")));\n{\"payload\": \"3q2+7w==\"}          // valid base64","handlingStrategy":"validation","validationCode":"private static final java.util.regex.Pattern B64 =\n    java.util.regex.Pattern.compile(\"^[A-Za-z0-9+/]*={0,2}$\");\nif (value == null || !B64.matcher(value).matches()) {\n  throw new IllegalArgumentException(\"Field must be Base64 encoded\");\n}","typeGuard":"boolean isBase64(String s) {\n  if (s == null || s.isEmpty()) return false;\n  try { java.util.Base64.getDecoder().decode(s); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":"try {\n  Buffer b = mapper.readValue(json, MyDto.class).getPayload();\n} catch (InputCoercionException e) {\n  // log offending token: e.getValue() — value was not Base64\n}","preventionTips":["Standardize on Base64 for binary fields across producers","Add Base64 validation at ingestion boundaries before Jackson mapping","Document payload encoding in API contracts to avoid hex/string confusion"],"tags":["json","base64","deserialization","jackson"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}