{"record":{"id":"cfc73140d259ed85","repo":"apache/cassandra","slug":"key-is-not-contained-in-the-given-ranges","errorCode":null,"errorMessage":"Key  is not contained in the given ranges","messagePattern":"Key  is not contained in the given ranges","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/sstable/format/SortedTableVerifier.java","lineNumber":445,"sourceCode":"\n        public RangeOwnHelper(List<Range<Token>> normalizedRanges)\n        {\n            this.normalizedRanges = normalizedRanges;\n            Range.assertNormalized(normalizedRanges);\n        }\n\n        /**\n         * check if the given key is contained in any of the given ranges\n         * <p>\n         * Must be called in sorted order - key should be increasing\n         *\n         * @param key the key\n         * @throws RuntimeException if the key is not contained\n         */\n        public void validate(DecoratedKey key)\n        {\n            if (!check(key))\n                throw new RuntimeException(\"Key \" + key + \" is not contained in the given ranges\");\n        }\n\n        /**\n         * check if the given key is contained in any of the given ranges\n         * <p>\n         * Must be called in sorted order - key should be increasing\n         *\n         * @param key the key\n         * @return boolean\n         */\n        public boolean check(DecoratedKey key)\n        {\n            assert lastKey == null || key.compareTo(lastKey) > 0;\n            lastKey = key;\n\n            if (normalizedRanges.isEmpty()) // handle tests etc. where we don't have any ranges\n                return true;\n","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/SortedTableVerifier.java#L427-L463","documentation":"The RangeOwnHelper.Validator.validate method throws when a DecoratedKey (or token) is not contained in any of the ranges supplied to the verifier. It is a sanity check used by verifyOwnedRanges during `nodetool verify` with owned-ranges checking: every key visited must belong to a range this node owns.","triggerScenarios":"Calling verify with owned-ranges checking when a visited partition key falls outside all provided ranges — e.g. token ownership changed between ring updates, ranges computed against a stale token metadata, or in tests calling validate() with a key outside the configured ranges.","commonSituations":"Topology changes mid-verify (node joining/leaving alters owned ranges); manually constructed range lists in tooling/tests (testRangeOwnHelper*) that omit the key's range; operating on a keyspace whose data predates a rebalance.","solutions":["Re-run verify after gossip/token ring is stable so ranges are computed consistently.","Run repair after topology changes so keys outside owned ranges are streamed to their new owners.","In tests/tooling, include the key's range in the range list passed to RangeOwnHelper (use Range.normalize/build from the key's token).","If using vnodes/multi-DC, ensure token metadata has fully propagated before verification."],"exampleFix":"// before: validate with ranges that don't cover the key\nToken tk = key.getToken(); // token outside ranges\nhelper.validator().validate(key); // throws\n// after: build ranges from actual ownership\nList<Range<Token>> ranges = Range.normalize(ownershipRangesFor(localToken));\nRangeOwnHelper helper = new RangeOwnHelper(ranges);\nhelper.validator().validate(key);","handlingStrategy":"validation","validationCode":"// Java: ensure ranges cover the key before validate\nRange<Token> r = primaryRangeFor(key.getToken());\nif (ranges.stream().noneMatch(x -> x.contains(key.getToken())))\n    throw new IllegalArgumentException(\"Range list does not cover token \" + key.getToken());","typeGuard":null,"tryCatchPattern":"try {\n    validator.validate(key);\n} catch (RuntimeException e) {\n    logger.warn(\"Key outside owned ranges; refresh token metadata and retry\", e);\n}","preventionTips":["Only run owned-range verification when token ring is stable (no pending joins/leaves)","After topology changes, run repair before verification","In tests, derive ranges from the same token metadata as the keys"],"tags":["ranges","tokens","verification","ownership"],"backgroundTag":"invalid-argument-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}