pinpoint-apm/pinpoint · error · java.lang.IllegalArgumentException
Invalid src byte array
Error message
Invalid src byte array: ${src} What it means
Base64Utils.decode(String) converts a 22-character URL-safe Base64 string back into a UUID. The library throws IllegalArgumentException immediately when the input is not exactly 22 ISO-8859-1 bytes, because that is the only length that decodes to the 16 bytes (two longs) a UUID requires. It is a fail-fast guard against malformed UUID strings before any decoding happens.
Solutions
- Verify the input is exactly 22 characters before calling decode
- Convert a standard UUID first: Base64Utils.encode(UUID.fromString(uuidString)) instead of passing the raw uuidString
- Strip Base64 padding characters ('=') and any URL-encoding before decoding
- Check where the string was produced; regenerate it with Base64Utils.encode on the writer side
Example fix
// before
UUID id = Base64Utils.decode(request.getParameter("id")); // crashes on 36-char UUID
// after
String raw = request.getParameter("id");
if (raw == null || raw.length() != 22) {
throw new IllegalArgumentException("expected 22-char base64 uuid, got: " + raw);
}
UUID id = Base64Utils.decode(raw); Defensive patterns
Strategy: validation
Validate before calling
if (src == null || src.length() != 22) {
throw new IllegalArgumentException("expected 22-char base64 uuid, got: " + src);
}
UUID id = Base64Utils.decode(src); Type guard
boolean isEncodedUuid(String s) {
return s != null && s.length() == 22;
} Try / catch
try {
UUID id = Base64Utils.decode(src);
} catch (IllegalArgumentException e) {
// fall back: treat src as a plain UUID string
UUID id = UUID.fromString(src);
} Prevention
- Always validate the 22-char length before decoding
- Never pass UUID.toString() output directly to decode; encode/decode symmetrically with Base64Utils
- Keep IDs as UUID objects end-to-end and only encode at the serialization boundary
- Beware URL-encoding and padding characters when IDs travel via HTTP
When it happens
Trigger: Calling Base64Utils.decode() with a string whose length is not 22 — e.g. a full 36-char UUID string with dashes, a Base64 string that still contains padding '=' characters, a truncated/corrupted ID, or passing a non-UUID value such as an agent ID or transaction ID.
Common situations: Developers pass a standard java.util.UUID.toString() output (with '-' separators, wrong length) instead of the Base64-formatted string produced by Base64Utils.encode(UUID); deserializing IDs from logs or HTTP parameters where the value was truncated or URL-encoded differently; mixing versions where one side emits padded 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
- agentIds size exceeds max limit. size: <agentIds.size()>…
- args size not equal
- class name must not be null
- invalid params
- limit must be positive or -1(unlimited)
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/d8e1acb59f0625a7.
Report an issue: GitHub.
Appendix: source
Thrown at commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/name/Base64Utils.java:103
return new String(encode, ISO_8859);
}
/**
* Decodes the given {@code src} string into a {@link UUID}. {@code src} must be a URL and filename safe base64
* encoded string 22 characters in length without pad characters "=".
*
* @param src string to be decoded into {@link UUID}
* @return uuid decoded from the given {@code src}
*
* @throws NullPointerException if {@code src} is null
* @throws IllegalArgumentException if {@code src} is not a URL and filename safe base64 encoded string without
* trailing pad characters
*/
public static UUID decode(String src) {
Objects.requireNonNull(src, "src");
byte[] bytes = src.getBytes(ISO_8859);
if (bytes.length != 22) {
throw new IllegalArgumentException("Invalid src byte array: " + src);
}
byte[] decoded = DECODER.decode(bytes);
long mostSigBits = BytesUtils.bytesToLong(decoded, 0);
long leastSigBits = BytesUtils.bytesToLong(decoded, BytesUtils.LONG_BYTE_LENGTH);
return new UUID(mostSigBits, leastSigBits);
}
}
View on GitHub (pinned to 744c3d3075)