{"record":{"id":"5968457c63de7416","repo":"apache/hadoop","slug":"unsupported-comparator-comparator","errorCode":null,"errorMessage":"Unsupported comparator: {comparator}","messagePattern":"Unsupported comparator: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java","lineNumber":2122,"sourceCode":"        }\n        String compClassName =\n            comparator.substring(COMPARATOR_JCLASS.length()).trim();\n        try {\n          // Resolve without running the class initializer, confirm it really\n          // is a RawComparator, and only then load and construct it.\n          Class<?> compClass =\n              Class.forName(compClassName, false, conf.getClassLoader());\n          RawComparator<Object> rawComparator =\n              (RawComparator<Object>) compClass.asSubclass(RawComparator.class)\n                  .getDeclaredConstructor().newInstance();\n          return new BytesComparator(rawComparator);\n        } catch (Exception e) {\n          throw new IllegalArgumentException(\n              \"Failed to instantiate comparator: \" + comparator + \"(\"\n                  + e.toString() + \")\");\n        }\n      } else {\n        throw new IllegalArgumentException(\"Unsupported comparator: \"\n            + comparator);\n      }\n    }\n\n    public void write(DataOutput out) throws IOException {\n      TFile.API_VERSION.write(out);\n      Utils.writeVLong(out, recordCount);\n      Utils.writeString(out, strComparator);\n    }\n\n    public long getRecordCount() {\n      return recordCount;\n    }\n\n    public void incRecordCount() {\n      ++recordCount;\n    }\n","sourceCodeStart":2104,"sourceCodeEnd":2140,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java#L2104-L2140","documentation":"IllegalArgumentException from makeComparator when the comparator string is non-empty, is not \"memcmp\", and does not start with \"jclass:\". Only three shapes are legal: \"\" (unsorted), \"memcmp\" (default byte order), and \"jclass:<fqcn>\". The string is persisted in the file, so an invalid name written at creation time also explodes on every subsequent read.","triggerScenarios":"Passing a hand-typed comparator name to new TFile.Writer(out, blockSize, comparatorName, conf): typos like \"jclas:\", \"Memcmp\", \"memcmp \", or a fully-qualified class name without the \"jclass:\" prefix. Also fires at read time for legacy files carrying arbitrary comparator names that older code tolerated.","commonSituations":"Config-driven comparator names where a typo survives to production, migration from code that treated the parameter as a free-form class name, or case/whitespace slips in generated job configs.","solutions":["Use the constants: TFile.COMPARATOR_MEMCMP (\"memcmp\") or TFile.COMPARATOR_JCLASS (\"jclass:\") concatenated with the class name.","Pass null or empty string for unsorted files instead of a descriptive label.","Validate the value before constructing the Writer: it must be \"\", \"memcmp\", or start with \"jclass:\"."],"exampleFix":"// before\nTFile.Writer w = new TFile.Writer(out, minBlockSize, \"MyComparator\", conf);\n// after\nString cmp = TFile.COMPARATOR_MEMCMP; // or TFile.COMPARATOR_JCLASS + MyKeyComparator.class.getName()\nTFile.Writer w = new TFile.Writer(out, minBlockSize, cmp, conf);","handlingStrategy":"validation","validationCode":"static String validComparator(String s) {\n  if (s == null || s.isEmpty()) return \"\"; // unsorted\n  if (TFile.COMPARATOR_MEMCMP.equals(s)) return s;\n  if (s.startsWith(TFile.COMPARATOR_JCLASS)) return s;\n  throw new IllegalArgumentException(\"Use TFile.COMPARATOR_MEMCMP or 'jclass:<fqcn>': \" + s);\n}\nTFile.Writer w = new TFile.Writer(out, minBlockSize, validComparator(name), conf);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never hand-type comparator strings; build them from TFile.COMPARATOR_* constants.","Validate config-sourced comparator names before the Writer constructor.","Remember the string is persisted: a typo poisons every future read of that file too."],"tags":["tfile","hadoop-common","comparator","invalid-argument","configuration"],"backgroundTag":"invalid-configuration-value","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}