alibaba/Sentinel · warning · IllegalArgumentException
Bad byte array
Error message
Bad byte array
What it means
StringDecoder is the codec in the netty-http command center that turns response bytes into a String using the configured Sentinel charset (SentinelConfig.charset()). decode(byte[], Charset) rejects null or zero-length byte arrays because new String(emptyBytes, charset) would produce a meaningless empty payload for a command response. It runs on the writeResponse path when encoding handler output.
Source
Thrown at sentinel-transport/sentinel-transport-netty-http/src/main/java/com/alibaba/csp/sentinel/transport/command/codec/StringDecoder.java:42
*
* @author Eric Zhao
*/
public class StringDecoder implements Decoder<String> {
@Override
public boolean canDecode(Class<?> clazz) {
return String.class.isAssignableFrom(clazz);
}
@Override
public String decode(byte[] bytes) throws Exception {
return decode(bytes, Charset.forName(SentinelConfig.charset()));
}
@Override
public String decode(byte[] bytes, Charset charset) {
if (bytes == null || bytes.length <= 0) {
throw new IllegalArgumentException("Bad byte array");
}
return new String(bytes, charset);
}
}
View on GitHub (pinned to a3f40ba8e9)
Solutions
- Make the custom CommandHandler always return a non-empty CommandResponse body (e.g. return an empty JSON array or a status string instead of null)
- Guard before decoding: if (bytes == null || bytes.length == 0) skip or substitute an empty-string response without the codec
- Test custom handlers against empty-input cases in the dashboard command flow
Example fix
// before (custom handler)
public CommandResponse<String> handle(CommandRequest req) {
return CommandResponse.ofSuccess(null); // -> StringDecoder throws on empty bytes
}
// after
public CommandResponse<String> handle(CommandRequest req) {
String body = computeBody(req);
return CommandResponse.ofSuccess(body == null || body.isEmpty() ? "{}" : body);
} Defensive patterns
Strategy: validation
Validate before calling
if (bytes == null || bytes.length == 0) {
return ""; // avoid invoking the decoder on an empty payload
}
return stringDecoder.decode(bytes, charset); Try / catch
try {
body = decoder.decode(bytes);
} catch (IllegalArgumentException e) {
body = ""; // empty response body instead of encoder failure
} Prevention
- Custom handlers must never return null bodies; return "[]" or "{}"
- Test custom commands against empty-result cases
When it happens
Trigger: A CommandHandler whose handle() returns an empty/absent body (e.g. returns null or an empty model), leading the encoder pipeline to invoke StringDecoder.decode with a null/empty byte array.
Common situations: Custom command handlers returning null or "" for edge-case inputs; modifying a handler so a branch returns nothing; versions where a handler's output for a command (e.g. /getRules variant) can be empty.
Related errors
- Bad class metadata
- Parameter key cannot be empty
- Metadata key cannot be empty
- Illegal port: ${port}
- Parameter key cannot be empty
AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14).
Data as JSON: /api/errors/952f9352fde9ab06.
Report an issue: GitHub.