elastic/elasticsearch · error · IllegalArgumentException

Resource count must be between 1 and 4

Error message

Resource count must be between 1 and 4

What it means

Thrown by the PoolingCuVSResourceManager constructor when the requested pool capacity is < 1 or > MAX_RESOURCES (4). The pool size is bounded because each ManagedCuVSResources holds a dedicated GPU resource and GPU memory; the hard cap of 4 prevents over-allocation.

Source

Thrown at libs/gpu-codec/src/main/java/org/elasticsearch/gpu/codec/CuVSResourceManager.java:126

        static class Holder {
            static final PoolingCuVSResourceManager INSTANCE = new PoolingCuVSResourceManager(
                MAX_RESOURCES,
                new RealGPUMemoryService(CuVSProvider.provider().gpuInfoProvider())
            );
        }

        private final ManagedCuVSResources[] pool;
        private final int capacity;
        private final GPUMemoryService gpuMemoryService;
        private int createdCount;

        ReentrantLock lock = new ReentrantLock();
        Condition enoughResourcesCondition = lock.newCondition();

        PoolingCuVSResourceManager(int capacity, GPUMemoryService gpuMemoryService) {
            if (capacity < 1 || capacity > MAX_RESOURCES) {
                throw new IllegalArgumentException("Resource count must be between 1 and " + MAX_RESOURCES);
            }
            this.capacity = capacity;
            this.gpuMemoryService = gpuMemoryService;
            this.pool = new ManagedCuVSResources[MAX_RESOURCES];
        }

        private ManagedCuVSResources getResourceFromPool() {
            for (int i = 0; i < createdCount; ++i) {
                var res = pool[i];
                if (res.isLocked() == false) {
                    return res;
                }
            }
            if (createdCount < capacity) {
                var delegate = createNew();
                if (delegate == null) {
                    logger.warn("Failed to create new GPU resource, will wait for an existing one");
                    return null;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Set the GPU resource count configuration to a value in [1, 4].
  2. If you genuinely need > 4 concurrent GPU resources, that exceeds the supported design; reduce concurrency or shard across nodes instead.
  3. Clamp the configured value to [1, 4] at the configuration layer with a clear validation message.

Example fix

// before: invalid capacity from config
int capacity = config.get("gpu.resources.count"); // 0 or 8
manager = new PoolingCuVSResourceManager(capacity, memService);

// after: validate and clamp
int capacity = config.get("gpu.resources.count");
if (capacity < 1 || capacity > 4) {
    throw new IllegalArgumentException("gpu.resources.count must be 1..4, got " + capacity);
}
manager = new PoolingCuVSResourceManager(capacity, memService);
Defensive patterns

Strategy: validation

Validate before calling

static int validatePoolCapacity(int configured) {
    if (configured < 1 || configured > 4) {
        throw new IllegalArgumentException("gpu resource count must be 1..4, got " + configured);
    }
    return configured;
}

Prevention

When it happens

Trigger: Constructing a PoolingCuVSResourceManager with a capacity value outside [1, 4]. This typically comes from configuration (e.g., a setting like index.gpu.codec.resources.count) being set to 0, negative, or greater than 4.

Common situations: A user setting the resource count setting to 0 (disable) or to a large number expecting more parallelism; a config parsing bug yielding 0; a test constructing the pool with an extreme value.

Related errors


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