prestodb/presto · error · java.lang.IllegalStateException

Malformed DN:

Error message

Malformed DN: 

What it means

getByte() decodes two hex characters into one byte; it throws "Malformed DN" when position+1 >= length, meaning there are fewer than two characters left to decode. Called from hexAV, res (escaped hex pairs like \AB), and getUTF8. The DN ends in the middle of a hex pair.

Source

Thrown at presto-client/src/main/java/okhttp/internal/tls/DistinguishedNameParser.java:329

                res = (res << 6) + (b & 0x3F);
            }
            return (char) res;
        }
        else {
            return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
        }
    }

    // Returns byte representation of a char pair
    // The char pair is composed of DN char in
    // specified 'position' and the next char
    // According to BNF syntax:
    // hexchar    = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
    //                    / "a" / "b" / "c" / "d" / "e" / "f"
    private int getByte(int position)
    {
        if (position + 1 >= length) {
            throw new IllegalStateException("Malformed DN: " + dn);
        }

        int b1;
        int b2;

        b1 = chars[position];
        if (b1 >= '0' && b1 <= '9') {
            b1 = b1 - '0';
        }
        else if (b1 >= 'a' && b1 <= 'f') {
            b1 = b1 - 87; // 87 = 'a' - 10
        }
        else if (b1 >= 'A' && b1 <= 'F') {
            b1 = b1 - 55; // 55 = 'A' - 10
        }
        else {
            throw new IllegalStateException("Malformed DN: " + dn);
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Reissue or obtain an intact certificate; verify with openssl x509 -text that the subject DN is complete.
  2. Fix the DN string in configuration so every \\XX escape has exactly two hex digits.
  3. Check for truncation when storing DNs (column length limits in databases, line breaks in files).
  4. Update presto-client/okhttp version if certificates use unusual encodings that newer parsers handle.

Example fix

// before
"DN": "CN=Server,O=Acme,C=US\\4A"  // truncated mid-escape
// after
"DN": "CN=Server,O=Acme,C=US\\4A2B"
Defensive patterns

Strategy: validation

Validate before calling

boolean escapesAreComplete(String dn) {
    if (dn == null) return false;
    for (int i = 0; i < dn.length(); i++) {
        if (dn.charAt(i) == '\\') {
            if (i + 2 >= dn.length()) return false; // needs two chars after backslash
            i += 2;
        }
    }
    return true;
}

Type guard

boolean hasTwoCharsAfterBackslash(String s) {
    return s == null || s.length() < 2 || s.lastIndexOf('\\') <= s.length() - 3;
}

Try / catch

try {
    subject.parse();
} catch (IllegalStateException e) {
    rejectCertificate("Truncated escape sequence in DN");
}

Prevention

When it happens

Trigger: An escaped hex pair like "CN=\\4" (single hex char at end of string) or a hex AV whose byte decoding runs past the end of the DN string.

Common situations: Truncated certificates or DN strings, DNs cut off in log/config copy-paste, or non-conforming CAs emitting odd-length escaped hex sequences.

Understand the failure class

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/a8a1038f49f7304b. Report an issue: GitHub.