phacility/phabricator · error · Exception
Invalid search engine type: %s. Valid types are: %s.
Error message
Invalid search engine type: %s. Valid types are: %s.
What it means
The service's `type` value does not match any installed fulltext storage engine identifier. Engines are collected with PhutilClassMapQuery over PhabricatorFulltextStorageEngine subclasses — `mysql` is built in, and `elasticsearch` exists only when the PhabricatorElasticsearchExtension is present. The message lists the identifiers actually available in this install.
Source
Thrown at src/infrastructure/cluster/config/PhabricatorClusterSearchConfigType.php:49
'type' => 'string',
'hosts' => 'optional list<map<string, wild>>',
'roles' => 'optional map<string, wild>',
'port' => 'optional int',
'protocol' => 'optional string',
'path' => 'optional string',
'version' => 'optional int',
));
} catch (Exception $ex) {
throw new Exception(
pht(
'Search engine configuration has an invalid service '.
'specification (at index "%s"): %s.',
$index,
$ex->getMessage()));
}
if (!array_key_exists($spec['type'], $engines)) {
throw new Exception(
pht(
'Invalid search engine type: %s. Valid types are: %s.',
$spec['type'],
implode(', ', array_keys($engines))));
}
if (isset($spec['hosts'])) {
foreach ($spec['hosts'] as $hostindex => $host) {
try {
PhutilTypeSpec::checkMap(
$host,
array(
'host' => 'string',
'roles' => 'optional map<string, wild>',
'port' => 'optional int',
'protocol' => 'optional string',
'path' => 'optional string',
'version' => 'optional int',View on GitHub (pinned to 5720a38cfe)
Solutions
- Use an identifier from the 'Valid types are' list in the error, exactly as printed.
- For Elasticsearch, install/enable PhabricatorElasticsearchExtension first, then set `type => 'elasticsearch'`.
- If no extension is intended, use the built-in `type => 'mysql'`.
Example fix
// before
array('type' => 'Elasticsearch'),
// after (extension enabled)
array('type' => 'elasticsearch'), Defensive patterns
Strategy: validation
Validate before calling
$valid = array_keys(
PhabricatorSearchService::loadAllFulltextStorageEngines());
if (!in_array($spec['type'], $valid, true)) {
throw new Exception(
'Engine "'.$spec['type'].'" not installed. Valid: '.implode(', ', $valid));
} Type guard
function isInstalledSearchEngine($type) {
$engines = PhabricatorSearchService::loadAllFulltextStorageEngines();
return isset($engines[$type]);
} Prevention
- Check the engine list (`bin/search` output or the Search Servers UI) before referencing a type in config.
- Treat identifiers as case-sensitive exact strings: 'mysql', 'elasticsearch'.
- Install and enable the Elasticsearch extension before, not after, writing cluster.search.
When it happens
Trigger: Setting `'type' => 'Elasticsearch'` or `'elastic'` (identifiers are case-sensitive), or setting `'elasticsearch'` without the Elasticsearch extension installed/enabled. The check runs at config-save time via PhabricatorClusterSearchConfigType::validateValue.
Common situations: Configuring search before installing the extension that provides the engine; engine identifiers renamed across Phabricator versions; copying config snippets from blog posts with different casing.
Related errors
- Search cluster configuration is not valid: each entry in the
- Search engine configuration has an invalid service specifica
- Search cluster configuration has an invalid host specificati
- The following regex is malformed and cannot be used: %s
- Search cluster has no hosts for role "%s".
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/cabdfc0669752a31.
Report an issue: GitHub.