elastic/elasticsearch · error · IllegalArgumentException

{} must be non-negative, got [{}]

Error message

{} must be non-negative, got [{}]

What it means

Thrown by CuVSGPUSupport.checkNonNegative when a GpuInfo record is constructed with a negative totalMemory value. GpuInfo is a record whose compact constructor calls checkNonNegative(totalMemory, "totalMemory"), enforcing the invariant that reported GPU total memory cannot be negative.

Source

Thrown at libs/gpu-codec/src/main/java/org/elasticsearch/gpu/CuVSGPUSupport.java:49

    private CuVSGPUSupport() {}

    private record GpuInfo(long totalMemory, String name) {

        static final GpuInfo UNSUPPORTED = new GpuInfo(0L, null);

        GpuInfo {
            checkNonNegative(totalMemory, "totalMemory");
        }
    }

    public static GPUSupport instance() {
        return INSTANCE;
    }

    static void checkNonNegative(long value, String name) {
        if (value < 0) {
            throw new IllegalArgumentException(name + " must be non-negative, got [" + value + "]");
        }
    }

    private static class Holder {
        static final GpuInfo GPU_INFO = initializeGpuInfo();
    }

    /**
     * Initializes GPU support information by finding the first compatible GPU.
     * Returns a {@link GpuInfo} with memory and name, or {@link GpuInfo#UNSUPPORTED} if no compatible GPU is found.
     */
    private static GpuInfo initializeGpuInfo() {
        try {
            var gpuInfoProvider = CuVSProvider.provider().gpuInfoProvider();
            LOG.info("Initializing GPU support with CuVS provider {}", gpuInfoProvider.getClass().getName());
            var availableGPUs = gpuInfoProvider.availableGPUs();
            if (availableGPUs.isEmpty()) {
                LOG.warn("No GPU found");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the source of the totalMemory value: if it comes from a GPU query that can fail, handle the failure sentinel (e.g., -1) before constructing GpuInfo.
  2. If no compatible GPU is available, use GpuInfo.UNSUPPORTED rather than constructing with a negative memory value.
  3. In tests, use realistic non-negative memory values or the UNSUPPORTED constant.

Example fix

// before: passing a negative sentinel from a failed query
long mem = queryTotalMemory(); // returns -1 on failure
GpuInfo info = new GpuInfo(mem, name); // throws

// after: guard the query result
long mem = queryTotalMemory();
if (mem < 0) {
    return GpuInfo.UNSUPPORTED;
}
GpuInfo info = new GpuInfo(mem, name);
Defensive patterns

Strategy: validation

Validate before calling

static GpuInfo safeGpuInfo(long totalMemory, String name) {
    if (totalMemory < 0) {
        return GpuInfo.UNSUPPORTED;
    }
    return new GpuInfo(totalMemory, name);
}

Prevention

When it happens

Trigger: Constructing a GpuInfo with totalMemory < 0, or a code path that initializes GpuInfo from a query (e.g., a CUDA/FFI call) returning a sentinel negative value when the GPU query fails. The record's compact constructor runs the check at construction time.

Common situations: A GPU detection/query routine returning -1 or another negative sentinel on failure (driver missing, device unavailable); unit tests constructing GpuInfo with bogus values; an FFI binding returning an error code that is misinterpreted as a memory size.

Related errors


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