elastic/elasticsearch · error · IllegalArgumentException

Dataset dimensions must be positive: rows={}, features={}

Error message

Dataset dimensions must be positive: rows={}, features={}

What it means

Thrown by CuVSIvfPqParamsFactory.create when either numVectors or dims is <= 0. This factory computes IVF-PQ (inverted file + product quantization) index parameters that require a concrete dataset shape; zero or negative dimensions make the parameter math meaningless, so it rejects up front.

Source

Thrown at libs/gpu-codec/src/main/java/org/elasticsearch/gpu/codec/CuVSIvfPqParamsFactory.java:50

     * Creates {@link CuVSIvfPqParams} with automatically calculated parameters based on the
     * dataset dimensions, distance metric, and efConstruction parameter.
     *
     * <p>This method replicates the parameter calculation logic from the C++ function:
     * {@code cuvs::neighbors::graph_build_params::ivf_pq_params(dataset_extents, metric)}
     *
     * @param numVectors the number of vectors in the dataset
     * @param dims the dimensionality of the vectors
     * @param distanceType the distance metric to use (e.g., L2Expanded, Cosine)
     * @param efConstruction the efConstruction parameter in an HNSW graph
     * @return a {@link CuVSIvfPqParams} instance with calculated parameters
     * @throws IllegalArgumentException if dimensions are invalid
     */
    static CuVSIvfPqParams create(int numVectors, int dims, CagraIndexParams.CuvsDistanceType distanceType, int efConstruction) {
        long nRows = numVectors;
        long nFeatures = dims;

        if (nRows <= 0 || nFeatures <= 0) {
            throw new IllegalArgumentException("Dataset dimensions must be positive: rows=" + nRows + ", features=" + nFeatures);
        }
        return createFromDimensions(nRows, nFeatures, distanceType, efConstruction);
    }

    /**
     * Creates {@link CuVSIvfPqParams} with automatically calculated parameters based on dataset
     * dimensions and construction parameter.
     *
     * <p>This is a convenience method when you have the dataset dimensions but not the dataset
     * object itself. The calculation logic is identical to {@link #create(int, int,
     * CagraIndexParams.CuvsDistanceType, int)}.
     *
     * @param nRows the number of rows (vectors) in the dataset
     * @param nFeatures the number of features (dimensions) per vector
     * @param distanceType the distance metric to use (e.g., L2Expanded, Cosine)
     * @param efConstruction the construction parameter for parameter calculation
     * @return a {@link CuVSIvfPqParams} instance with calculated parameters
     * @throws IllegalArgumentException if dimensions are invalid

View on GitHub (pinned to db6a809a66)

Solutions

  1. Ensure the dataset has at least one vector and dims is a positive integer before calling create.
  2. If the dataset can be empty at this point, skip IVF-PQ parameter computation until vectors are present.
  3. Validate the field mapping's dims setting is positive (Elasticsearch dense_vector dims are 1..4096).

Example fix

// before: calling create on an empty dataset
CuVSIvfPqParams params = CuVSIvfPqParamsFactory.create(0, dims, distanceType, ef);

// after: guard for non-empty dataset
if (numVectors <= 0 || dims <= 0) {
    throw new IllegalStateException("cannot build IVF-PQ params: dataset is empty or dims invalid");
}
CuVSIvfPqParams params = CuVSIvfPqParamsFactory.create(numVectors, dims, distanceType, ef);
Defensive patterns

Strategy: validation

Validate before calling

static CuVSIvfPqParams safeCreate(int numVectors, int dims, CagraIndexParams.CuvsDistanceType dt, int ef) {
    if (numVectors <= 0 || dims <= 0) {
        throw new IllegalStateException("cannot compute IVF-PQ params: numVectors=" + numVectors + ", dims=" + dims);
    }
    return CuVSIvfPqParamsFactory.create(numVectors, dims, dt, ef);
}

Try / catch

try {
    return CuVSIvfPqParamsFactory.create(numVectors, dims, dt, ef);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Dataset dimensions must be positive")) {
        // defer parameter computation until dataset is populated
        return null;
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling CuVSIvfPqParamsFactory.create(numVectors, dims, distanceType, efConstruction) with numVectors <= 0 or dims <= 0. The values are widened to long (nRows, nFeatures) and checked: nRows <= 0 || nFeatures <= 0 triggers the throw.

Common situations: An empty or not-yet-populated dataset passed to the factory (numVectors = 0); a vector dimension config of 0 from a misconfigured mapping; a bug computing dims from the model definition that yields 0 or negative.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/fcee496de0667994. Report an issue: GitHub.