{"record":{"id":"8134ed10e6c0feb6","repo":"elastic/elasticsearch","slug":"negative-number-of-vectors","errorCode":null,"errorMessage":"negative number of vectors: {}","messagePattern":"negative number of vectors: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/gpu-codec/src/main/java/org/elasticsearch/gpu/codec/DatasetUtilsImpl.java","lineNumber":68,"sourceCode":"            throwIllegalArgumentException(numVectors, dims);\n        }\n        final int byteSize = dataType == CuVSMatrix.DataType.FLOAT ? Float.BYTES : Byte.BYTES;\n        if (((long) numVectors * dims * byteSize) > input.byteSize()) {\n            throwIllegalArgumentException(input, numVectors, dims);\n        }\n        return fromMemorySegment(input, numVectors, dims, dataType);\n    }\n\n    static void throwIllegalArgumentException(MemorySegment ms, int numVectors, int dims) {\n        var s = \"segment of size [\" + ms.byteSize() + \"] too small for expected \" + numVectors + \" float vectors of \" + dims + \" dims\";\n        throw new IllegalArgumentException(s);\n    }\n\n    static void throwIllegalArgumentException(int numVectors, int dims) {\n        String s;\n        if (numVectors < 0) {\n            s = \"negative number of vectors: \" + numVectors;\n        } else {\n            s = \"negative vector dims: \" + dims;\n        }\n        throw new IllegalArgumentException(s);\n    }\n}\n","sourceCodeStart":50,"sourceCodeEnd":74,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/gpu-codec/src/main/java/org/elasticsearch/gpu/codec/DatasetUtilsImpl.java#L50-L74","documentation":"Thrown by DatasetUtilsImpl.fromInput() when the numVectors parameter is negative. This is a pre-condition check: the method validates that both numVectors and dims are non-negative before computing the required byte size. When numVectors is negative, this specific message is produced.","triggerScenarios":"Calling DatasetUtils.getInstance().fromInput(segment, numVectors, dims, dataType) with numVectors < 0. In practice this can happen if FloatVectorValues.size() returns a negative value due to a corrupted index, or if an arithmetic overflow/underflow produces a negative count upstream.","commonSituations":"Corrupted segment metadata causing size() to return -1 or another sentinel negative value; integer underflow when computing numVectors from a subtraction; unit test passing invalid synthetic values.","solutions":["Check the upstream source of numVectors — if it comes from FloatVectorValues.size(), verify the index is not corrupted.","Add a guard before calling fromInput: if (numVectors < 0) throw early with context about where the negative value originated.","Run lucene CheckIndex on the affected shard to detect corruption."],"exampleFix":"// before\nint numVectors = floatVectorValues.size(); // could be negative if corrupted\nCuVSMatrix m = DatasetUtils.getInstance().fromInput(seg, numVectors, dims, type);\n\n// after\nint numVectors = floatVectorValues.size();\nif (numVectors < 0) {\n    throw new IllegalStateException(\"Unexpected negative vector count \" + numVectors + \" for field \" + fieldName);\n}\nCuVSMatrix m = DatasetUtils.getInstance().fromInput(seg, numVectors, dims, type);","handlingStrategy":"validation","validationCode":"if (numVectors < 0) {\n    throw new IllegalStateException(\"numVectors must be non-negative, got: \" + numVectors);\n}\nCuVSMatrix m = DatasetUtils.getInstance().fromInput(segment, numVectors, dims, dataType);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always validate numVectors >= 0 before calling fromInput.","If numVectors comes from FloatVectorValues.size(), check the return value — a corrupted index can return negative sentinels.","Use defensive checks at API boundaries where external data feeds into vector count parameters."],"tags":["gpu-codec","vector-search","validation","cuvs"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}