{"record":{"id":"f44b820d853ff615","repo":"eclipse-vertx/vert.x","slug":"expected-a-base64-encoded-byte-array-f44b82","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/ByteArrayDeserializer.java","lineNumber":32,"sourceCode":"import tools.jackson.core.exc.InputCoercionException;\nimport tools.jackson.databind.DeserializationContext;\nimport tools.jackson.databind.deser.std.StdDeserializer;\n\nimport static io.vertx.core.json.impl.JsonUtil.BASE64_DECODER;\n\nclass ByteArrayDeserializer extends StdDeserializer<byte[]> {\n\n  ByteArrayDeserializer() {\n    super(byte[].class);\n  }\n\n  @Override\n  public byte[] deserialize(JsonParser p, DeserializationContext ctxt) {\n    String text = p.getString();\n    try {\n      return BASE64_DECODER.decode(text);\n    } catch (IllegalArgumentException e) {\n      throw new InputCoercionException(p, \"Expected a base64 encoded byte array\", p.currentToken(), byte[].class);\n    }\n  }\n}\n","sourceCodeStart":14,"sourceCodeEnd":36,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/ByteArrayDeserializer.java#L14-L36","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the producer to emit standard Base64: Base64.getEncoder().encodeToString(bytes).","If the source is URL-safe Base64, normalize it first (replace '-' with '+' and '_' with '/') before decoding, or configure a deserializer that uses Base64.getUrlDecoder().","Strip whitespace/newlines from the string; java.util.Base64 rejects any character outside the alphabet.","If the value is actually hex or plain text, change the target field type to String and decode manually."],"exampleFix":"// before\n{\"data\": \"68656c6c6f\"} // hex string in byte[] field\n// after\n{\"data\": \"aGVsbG8=\"} // standard Base64","handlingStrategy":"validation","validationCode":"static boolean isStandardBase64(String s) {\n  return s != null && !s.isEmpty() && s.matches(\"[A-Za-z0-9+/]*={0,2}\");\n}","typeGuard":"if (raw instanceof String s && isStandardBase64(s)) { byte[] data = Base64.getDecoder().decode(s); }","tryCatchPattern":"try {\n  byte[] data = Base64.getDecoder().decode(text);\n} catch (IllegalArgumentException e) {\n  throw new IllegalArgumentException(\"Field 'data' is not standard Base64: \" + text, e);\n}","preventionTips":["Always produce binary fields with Base64.getEncoder() on the producer side.","Reject non-conforming strings at the API edge with a regex or strict decoder.","Agree on a single Base64 alphabet (standard vs URL-safe) in the API contract."],"tags":["json","base64","deserialization","jackson"],"backgroundTag":"invalid-argument-format","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"}