quarkusio/quarkus · error · IllegalArgumentException
Expected a base64 encoded byte array, got: ${text}
Error message
Expected a base64 encoded byte array, got: ${text} What it means
DevUIRecorder.createVertxJsonMapper installs a JSON type adapter mapping vert.x Buffer to a base64-encoded string. When decoding incoming text back into a Buffer, a non-base64 string causes IllegalArgumentException, which is rethrown with 'Expected a base64 encoded byte array, got: <text>'. This means the JSON-RPC client sent something that is not valid base64 where a Buffer was expected.
Source
Thrown at extensions/devui/runtime/src/main/java/io/quarkus/devui/runtime/DevUIRecorder.java:57
@Recorder
public class DevUIRecorder {
private static final Logger LOG = Logger.getLogger(DevUIRecorder.class);
public void initializeJsonRpcCodec(BeanContainer beanContainer) {
JsonRpcRouter jsonRpcRouter = beanContainer.beanInstance(JsonRpcRouter.class);
jsonRpcRouter.initializeCodec(createVertxJsonMapper());
}
public static JsonMapper createVertxJsonMapper() {
JsonMapper.Factory factory = JsonMapper.Factory.deploymentLinker().createLink(
DevConsoleManager.getGlobal(DevJsonRpcRecorder.DEV_MANAGER_GLOBALS_JSON_MAPPER_FACTORY));
return factory.create(new JsonTypeAdapter<>(JsonObject.class, JsonObject::getMap, JsonObject::new),
new JsonTypeAdapter<>(JsonArray.class, JsonArray::getList, JsonArray::new),
new JsonTypeAdapter<>(Buffer.class, buffer -> BASE64_ENCODER.encodeToString(buffer.getBytes()), text -> {
try {
return Buffer.buffer(BASE64_DECODER.decode(text));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Expected a base64 encoded byte array, got: " + text, e);
}
}));
}
public void shutdownTask(ShutdownContext shutdownContext, String devUIBasePath) {
shutdownContext.addShutdownTask(new DeleteDirectoryRunnable(devUIBasePath));
}
public Handler<RoutingContext> devUIWebSocketHandler() {
return new DevUIWebSocketHandler();
}
public Handler<RoutingContext> uiHandler(String finalDestination,
String path,
List<FileSystemStaticHandler.StaticWebRootConfiguration> webRootConfigurations,
ShutdownContext shutdownContext) {
WebJarStaticHandler handler = new WebJarStaticHandler(finalDestination, path, webRootConfigurations);View on GitHub (pinned to e1c734241f)
Solutions
- Send the payload as proper base64 (Base64.getEncoder().encodeToString(bytes))
- Strip any 'data:...;base64,' prefix before sending
- Decode/validate client-side first (e.g. atob or Buffer.from with 'base64' and strict check)
Example fix
// before
rpc.call('sendBuffer', { data: fileText });
// after
rpc.call('sendBuffer', { data: btoa(unescape(encodeURIComponent(fileText))) }); Defensive patterns
Strategy: try-catch
Validate before calling
// client side
const b64 = /^([A-Za-z0-9+/=\r\n]+)$/;
if (!b64.test(payload)) throw new Error("payload must be plain base64"); Try / catch
try { rpc.call('method', { data: payload }); }
catch (e) {
if (String(e.message).startsWith('Expected a base64 encoded byte array')) {
// re-encode payload as base64 and retry once
} else { throw e; }
} Prevention
- Always base64-encode binary payloads before JSON-RPC calls
- Strip data-URI prefixes before sending
- Validate with a base64 regex client-side
When it happens
Trigger: A Dev UI JSON-RPC call passing a plain string, hex, or data-URI (e.g. 'data:...;base64,...') where a Buffer/base64 byte array parameter is expected; called via initializeJsonRpcCodec.
Common situations: Front-end code sending raw text or a data URL instead of stripping the prefix and base64-encoding the payload; corrupted payloads from hand-rolled JSON-RPC clients.
Related errors
- The level of the root logger cannot be set to null
- Not Allowed
- java.lang.RuntimeException wrapping the underlying Interrupt
- Failed to find any non-blocking provider for startup actions
- Failed to find any non-blocking provider for startup actions
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/808ee7166b7344ff.
Report an issue: GitHub.