pxb1988/dex2jar · error · UTFDataFormatException

String more than 65535 UTF bytes long

Error message

String more than 65535 UTF bytes long

What it means

Thrown by Mutf8.countBytes (via utfCount) when the MUTF-8 encoding of a string exceeds 65535 bytes while shortLength is set. Modified UTF-8 uses an unsigned 16-bit length prefix, so longer strings cannot be encoded.

Solutions

  1. Shorten the string before writing (truncate or hash long identifiers)
  2. Split the string into multiple entries if the format allows
  3. Pass shortLength=false if the surrounding format actually uses a larger length field

Example fix

// before
if (Mutf8.utfCount(s, true) > 65535) { /* throws anyway when counting */ }
// after
byte[] b = Mutf8.encode(s);
if (b.length > 65535) {
    s = s.substring(0, 20000) + "..." + Integer.toHexString(s.hashCode());
}
Defensive patterns

Strategy: validation

Validate before calling

if (Mutf8.utfCount(s, true) > 65535) { throw new IllegalArgumentException("string too long for MUTF-8 short form"); }

Type guard

null

Try / catch

try { utfCount(s, true); } catch (UTFDataFormatException e) { s = truncate(s); }

Prevention

When it happens

Trigger: Calling utfCount/encode on a string whose MUTF-8 representation is over 65535 bytes (e.g. ~21845 CJK characters at 3 bytes each).

Common situations: Writing very long method names, string constants, or concatenated identifiers into DEX/class files with the 16-bit length limit; long debug strings.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08). Data as JSON: /api/errors/483444e1b6a43e4b. Report an issue: GitHub.

Appendix: source

Thrown at dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java:80

    }

    /**
     * Returns the number of bytes the modified UTF8 representation of 's' would take.
     */
    private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
        long result = 0;
        final int length = s.length();
        for (int i = 0; i < length; ++i) {
            char ch = s.charAt(i);
            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
                ++result;
            } else if (ch <= 2047) {
                result += 2;
            } else {
                result += 3;
            }
            if (shortLength && result > 65535) {
                throw new UTFDataFormatException("String more than 65535 UTF bytes long");
            }
        }
        return result;
    }

    /**
     * Encodes the modified UTF-8 bytes corresponding to {@code s} into {@code dst}, starting at {@code offset}.
     */
    public static void encode(byte[] dst, int offset, String s) {
        final int length = s.length();
        for (int i = 0; i < length; i++) {
            char ch = s.charAt(i);
            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
                dst[offset++] = (byte) ch;
            } else if (ch <= 2047) {
                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
                dst[offset++] = (byte) (0x80 | (0x3f & ch));
            } else {

View on GitHub (pinned to b5bda4fb49)