elastic/elasticsearch · error · IllegalArgumentException

wildcard only supports a single value, please use comma-sepa

Error message

wildcard only supports a single value, please use comma-separated values or a single wildcard value

What it means

Thrown by TransportGetDatabaseConfigurationAction.createActionContext (coordinating/master node) when the GET request supplies more than one id AND at least one of them is a wildcard pattern (contains '*', '?', or other Regex.isSimpleMatchPattern metacharacters). Mixing concrete ids with wildcards, or multiple wildcards, is disallowed; you must use either a single wildcard or a comma-separated list of concrete ids.

Source

Thrown at modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/direct/TransportGetDatabaseConfigurationAction.java:88

            actionFilters,
            GetDatabaseConfigurationAction.NodeRequest::new,
            threadPool.executor(ThreadPool.Names.MANAGEMENT)
        );
        this.databaseNodeService = databaseNodeService;
        this.projectResolver = projectResolver;
    }

    protected List<DatabaseConfigurationMetadata> createActionContext(Task task, GetDatabaseConfigurationAction.Request request) {
        final Set<String> ids;
        if (request.getDatabaseIds().length == 0) {
            // if we did not ask for a specific name, then return all databases
            ids = Set.of("*");
        } else {
            ids = new LinkedHashSet<>(Arrays.asList(request.getDatabaseIds()));
        }

        if (ids.size() > 1 && ids.stream().anyMatch(Regex::isSimpleMatchPattern)) {
            throw new IllegalArgumentException(
                "wildcard only supports a single value, please use comma-separated values or a single wildcard value"
            );
        }
        List<DatabaseConfigurationMetadata> results = new ArrayList<>();
        ProjectMetadata projectMetadata = projectResolver.getProjectMetadata(clusterService.state());
        PersistentTasksCustomMetadata tasksMetadata = PersistentTasksCustomMetadata.get(projectMetadata);
        String geoIpTaskId = GeoIpDownloaderTaskExecutor.getTaskId(projectMetadata.id(), projectResolver.supportsMultipleProjects());

        for (String id : ids) {
            results.addAll(getWebDatabases(geoIpTaskId, tasksMetadata, id));
            results.addAll(getMaxmindDatabases(projectMetadata, id));
        }
        return results;
    }

    /*
     * This returns read-only database information about the databases managed by the standard downloader
     */

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use a single wildcard by itself: GET _ingest/geoip/database/* or GET _ingest/geoip/database/city*.
  2. Use a comma-separated list of concrete (non-wildcard) ids: GET _ingest/geoip/database/a,b,c.
  3. Split into two requests: one wildcard call and one explicit-id call.

Example fix

// before
GET _ingest/geoip/database/city-db,*

// after
GET _ingest/geoip/database/*
Defensive patterns

Strategy: validation

Validate before calling

// Before GET, ensure no wildcard mixing
List<String> ids = Arrays.asList(requestIds);
boolean hasWildcard = ids.stream().anyMatch(s -> s.matches(".*[*?].*"));
if (ids.size() > 1 && hasWildcard) {
    throw new IllegalArgumentException("Use a single wildcard OR a list of concrete ids, not both");
}

Prevention

When it happens

Trigger: GET _ingest/geoip/database/a,b* or GET _ingest/geoip/database/*,city-db. Any combination where ids.size() > 1 and any id matches a wildcard pattern trips the guard on the master/coordination path.

Common situations: Building a 'fetch these plus everything matching that prefix' query in one call; passing an array of ids that accidentally includes a glob; UI that appends '*' to a filter alongside selected names.

Related errors


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