{"id":"469f3fa1e23d8a28","repo":"apache/kafka","slug":"input-string-with-prefix-str-substring-0-24-is","errorCode":null,"errorMessage":"Input string with prefix `str.substring(0, 24)` is too long to be decoded as a base64 UUID","messagePattern":"Input string with prefix `str\\.substring\\(0, 24\\)` is too long to be decoded as a base64 UUID","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/Uuid.java","lineNumber":136,"sourceCode":"    public int hashCode() {\n        long xor = mostSignificantBits ^ leastSignificantBits;\n        return (int) (xor >> 32) ^ (int) xor;\n    }\n\n    /**\n     * Returns a base64 string encoding of the UUID.\n     */\n    @Override\n    public String toString() {\n        return Base64.getUrlEncoder().withoutPadding().encodeToString(getBytesFromUuid());\n    }\n\n    /**\n     * Creates a UUID based on a base64 string encoding used in the toString() method.\n     */\n    public static Uuid fromString(String str) {\n        if (str.length() > 24) {\n            throw new IllegalArgumentException(\"Input string with prefix `\"\n                + str.substring(0, 24) + \"` is too long to be decoded as a base64 UUID\");\n        }\n\n        ByteBuffer uuidBytes = ByteBuffer.wrap(Base64.getUrlDecoder().decode(str));\n        if (uuidBytes.remaining() != 16) {\n            throw new IllegalArgumentException(\"Input string `\" + str + \"` decoded as \"\n                + uuidBytes.remaining() + \" bytes, which is not equal to the expected 16 bytes \"\n                + \"of a base64-encoded UUID\");\n        }\n\n        return new Uuid(uuidBytes.getLong(), uuidBytes.getLong());\n    }\n\n    private byte[] getBytesFromUuid() {\n        // Extract bytes for uuid which is 128 bits (or 16 bytes) long.\n        ByteBuffer uuidBytes = ByteBuffer.wrap(new byte[16]);\n        uuidBytes.putLong(this.mostSignificantBits);\n        uuidBytes.putLong(this.leastSignificantBits);","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/Uuid.java#L118-L154","documentation":"Thrown by Uuid.fromString when the input string is longer than 24 characters — base64-url encoding of a 128-bit UUID is at most 22 chars plus optional padding, so anything over 24 cannot decode to 16 bytes. Uuid.fromString is the inverse of Uuid.toString(), which uses Base64.getUrlEncoder().withoutPadding(); passing a standard hyphenated java.util.UUID string (36 chars) or any non-Kafka UUID format triggers this. It is a guard against misusing the Kafka-internal base64 Uuid format (used for topic IDs and similar) with external UUID formats.","triggerScenarios":"Calling Uuid.fromString with: a java.util.UUID.toString() value like \"123e4567-e89b-12d3-a456-426614174000\" (36 chars); a canonical hex UUID; a topic name mistaken for a topic ID; any base64 string longer than 24 chars; a string with embedded newlines/whitespace inflating its length.","commonSituations":"Treating Kafka's org.apache.kafka.common.Uuid like java.util.UUID and feeding it standard-format UUIDs; passing a topic *name* into an API that wants a topic *id* (KIP-516 topic IDs); copying UUID strings between systems that use different encodings; trimming/parsing bugs that leave extra characters; loading IDs from JSON/DB where they were stored in canonical form.","solutions":["Use the value produced by Uuid.toString() (base64-url, no padding, <=22 chars) as the input to Uuid.fromString — these two methods are a matched pair.","If you have a java.util.UUID, convert via new UUID(mostSigBits, leastSigBits) then construct org.apache.kafka.common.Uuid from its longs, or base64-encode its 16 bytes yourself.","Double-check you are passing a topic ID (base64) and not a topic name into Admin APIs that take Uuid.","Trim and validate the string length (<=22 ideally) before calling fromString; reject canonical-format UUIDs upstream."],"exampleFix":"// before\nUuid k = Uuid.fromString(\"550e8400-e29b-41d4-a716-446655440000\");  // 36 chars -> throws 299\n\n// after\njava.util.UUID ju = java.util.UUID.fromString(\"550e8400-e29b-41d4-a716-446655440000\");\nUuid k = new Uuid(ju.getMostSignificantBits(), ju.getLeastSignificantBits());\n// or, round-trip a Kafka Uuid: Uuid.fromString(k.toString())","handlingStrategy":"validation","validationCode":"// Pre-validate length and base64-alphabet before calling Uuid.fromString:\nimport java.util.Base64;\nimport java.util.regex.Pattern;\n\nprivate static final Pattern B64URL_NO_PAD = Pattern.compile(\"^[A-Za-z0-9_-]{0,24}$\");\n\npublic static boolean isParsableUuid(String s) {\n    if (s == null || s.length() > 24 || !B64URL_NO_PAD.matcher(s).matches()) return false;\n    try {\n        byte[] decoded = Base64.getUrlDecoder().decode(s);\n        return decoded.length == 16;\n    } catch (IllegalArgumentException ex) {\n        return false;\n    }\n}\n\n// Usage:\nif (!isParsableUuid(candidate)) {\n    throw new IllegalArgumentException(\"Not a base64-encoded Kafka Uuid: \" + candidate);\n}\nUuid id = Uuid.fromString(candidate);","typeGuard":"import java.util.Base64;\nimport java.util.regex.Pattern;\n\nprivate static final Pattern KAFKA_UUID = Pattern.compile(\"^[A-Za-z0-9_-]{1,24}$\");\n\npublic static boolean isKafkaUuidString(Object o) {\n    if (!(o instanceof String)) return false;\n    String s = (String) o;\n    if (!KAFKA_UUID.matcher(s).matches()) return false;\n    try {\n        return Base64.getUrlDecoder().decode(s).length == 16;\n    } catch (IllegalArgumentException ex) {\n        return false;\n    }\n}\n\n// TypeScript variant (if consuming via TS bridge):\n// export const isKafkaUuid = (s: unknown): s is string =>\n//   typeof s === \"string\" && /^[A-Za-z0-9_-]{1,24}$/.test(s) &&\n//   Buffer.from(s, \"base64url\").length === 16;","tryCatchPattern":"try {\n    Uuid id = Uuid.fromString(input);\n} catch (IllegalArgumentException e) {\n    // Distinguish kafka topic-id Uuids from java.util.UUID strings at the boundary:\n    throw new IllegalArgumentException(\"Expected a Kafka base64url Uuid (<=24 chars, 16 bytes), got: \"\n        + (input == null ? \"null\" : \"'\" + input.substring(0, Math.min(input.length(), 24)) + \"'\"), e);\n}","preventionTips":["Remember Kafka's org.apache.kafka.common.Uuid is NOT java.util.UUID — it uses base64url (no padding, up to 24 chars), not the dashed hex form.","Validate length and charset at ingress before calling fromString; reject anything > 24 chars or containing non base64url characters.","When passing topic IDs between services, use Uuid.toString()/fromString() consistently and never mix with java.util.UUID.fromString()."],"tags":["uuid","base64","topic-id","parsing"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}