{"record":{"id":"c71f6dc475de09c8","repo":"apache/seatunnel","slug":"startrowkey-can-t-be-bigger-than-endrowkey","errorCode":null,"errorMessage":"startRowkey can't be bigger than endRowkey","messagePattern":"startRowkey can't be bigger than endRowkey","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-hbase/src/main/java/org/apache/seatunnel/connectors/seatunnel/hbase/util/HBaseUtil.java","lineNumber":43,"sourceCode":"\npublic class HBaseUtil {\n\n    public static byte[] convertRowKey(String rowKey, boolean isBinary) {\n        if (StringUtils.isEmpty(rowKey)) {\n            return HConstants.EMPTY_BYTE_ARRAY;\n        }\n\n        if (isBinary) {\n            return Bytes.toBytesBinary(rowKey);\n        } else {\n            return Bytes.toBytes(rowKey);\n        }\n    }\n\n    public static void validateRowKeyRange(byte[] startRowKey, byte[] endRowKey) {\n        if (startRowKey.length > 0 && endRowKey.length > 0) {\n            if (Bytes.compareTo(startRowKey, endRowKey) > 0) {\n                throw new IllegalArgumentException(\"startRowkey can't be bigger than endRowkey\");\n            }\n        }\n    }\n}\n","sourceCodeStart":25,"sourceCodeEnd":48,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-hbase/src/main/java/org/apache/seatunnel/connectors/seatunnel/hbase/util/HBaseUtil.java#L25-L48","documentation":"Thrown by HBaseUtil.validateRowKeyRange when both startRowkey and endRowkey are configured and the start rowkey is lexicographically greater than the end rowkey (byte-wise comparison). A scan with such a range would return nothing or behave incorrectly, so SeaTunnel rejects the configuration up front.","triggerScenarios":"Setting 'startRowkey' > 'endRowkey' in byte order in the HBase source config — e.g. startRowkey=\"z\", endRowkey=\"a\" — triggers validateRowKeyRange during connector setup.","commonSituations":"Swapped start/end rowkey values in config; binary (non-string) rowkeys configured with values whose byte order differs from what the user expects; copy-paste errors when narrowing a scan range.","solutions":["Swap the values so startRowkey is lexicographically (byte-wise) less than or equal to endRowkey.","Remember comparison is byte-wise, not locale order — check the raw bytes of your rowkeys if they are binary.","Remove one of the bounds if you intended an open-ended scan (empty startRowkey or endRowkey skips the check).","Test the rowkey range in the HBase shell with a Scan to confirm expected data before submitting the job."],"exampleFix":"// before\nstartRowkey = \"z\"\nendRowkey = \"a\"\n// after\nstartRowkey = \"a\"\nendRowkey = \"z\"","handlingStrategy":"validation","validationCode":"import org.apache.hadoop.hbase.util.Bytes;\nif (startRowkey.length > 0 && endRowkey.length > 0\n    && Bytes.compareTo(startRowkey.getBytes(), endRowkey.getBytes()) > 0) {\n  throw new IllegalArgumentException(\"startRowkey must be <= endRowkey\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  hbaseSource.validate();\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"startRowkey can't be bigger\")) {\n    // swap bounds or clear one before re-submitting\n  }\n}","preventionTips":["Validate rowkey ordering in config-load tooling before submission.","For binary rowkeys, generate config values from the raw bytes, not human-readable strings.","Leave startRowkey/endRowkey empty for open-ended scans.","Add unit tests for scan-range configs."],"tags":["hbase","rowkey","validation","config"],"backgroundTag":"invalid-argument-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}