Applies to: Mattermost Server v11.6 and later, Elasticsearch/AWS OpenSearch search backend, EnableCJKAnalyzers setting, particularly relevant to Kubernetes/multi-node deployments.
Symptoms: Korean (or other CJK) search returns no results, or config changes intended to enable CJK search do not take effect consistently.
🛑 Problem
Mattermost's Korean/Japanese/Chinese search support relies on the EnableCJKAnalyzers server setting (available from v11.6), together with a CJK analyzer plugin (for example, analysis-nori for Korean) installed on the Elasticsearch or OpenSearch cluster. This is a whole-morpheme/whole-word matcher, not a substring matcher, a separate, unrelated legacy behavior (a database LIKE-based substring match, controlled by the CjkSearch flag) only applies when Elasticsearch/OpenSearch search is turned off entirely, and only covers message text and hashtags, not attachments. In containerized deployments with multiple app pods/nodes, if configuration is stored in per-pod config.json files rather than the database, a mmctl config set command reaching one pod through a load balancer will only update that pod, leaving others with the old value and producing inconsistent behavior on every check.
Symptoms
- Korean search results are missing after switching to OpenSearch, especially for partial/substring-style queries.
-
mmctl config getreturns different values for the same setting on different checks. - Server logs show:
EnableCJKAnalyzers is set but no CJK analyzer plugins found installed. Please review opensearch settings.
âś… Solution
Install the CJK analyzer plugin on the search cluster, enable EnableCJKAnalyzers consistently across all app nodes, and rebuild the search index.
Enable CJK analyzers and rebuild the index
- Install the relevant analyzer plugin on your Elasticsearch/OpenSearch cluster (for AWS OpenSearch Service, associate the plugin through the AWS console rather than the on-premises
opensearch-plugin installcommand). - Ensure Enable Elasticsearch for search queries is turned on; the CJK setting is rejected if this is off.
- Set the setting consistently:
- Single-node/file-based config: set
ElasticsearchSettings.EnableCJKAnalyzersinconfig.json. - Database-backed config: use
mmctl config set ElasticsearchSettings.EnableCJKAnalyzers trueand verify withmmctl config get ElasticsearchSettings.EnableCJKAnalyzers. -
Multi-pod/Kubernetes deployments where config.json cannot be edited in-pod: set the environment variable on every pod instead:
MM_ELASTICSEARCHSETTINGS_ENABLECJKANALYZERS=true
(and
MM_ELASTICSEARCHSETTINGS_ENABLESEARCHING=trueif that setting is also managed this way), then restart all pods.
- Single-node/file-based config: set
- Restart the server so the analyzer registers. Confirm in the startup log for a line indicating the analyzer is active; a plugin-not-found warning means the analyzer plugin is not actually installed on the search cluster.
- Rebuild the index: in System Console > Environment > Elasticsearch (this menu label is used even when the backend is OpenSearch), click Purge Indexes, then run Bulk Indexing. Enabling the setting only affects newly indexed content, existing posts must be reindexed to pick up the new analyzer.
To minimize user-facing impact during a large reindex: temporarily disable Enable Elasticsearch for search queries (falling back to database search), run Bulk Indexing to completion, then re-enable it. Indexing time scales with the size of the post database; watch the job's "N% Complete" indicator to estimate completion, and consider running during off-peak hours.
⚠️ Important: In multi-node/Kubernetes deployments, every node must use identical configuration. If configuration is stored in per-pod files, an
mmctl config setreaching only one pod via a load balancer will not propagate to the others, producing inconsistentconfig getresults even after a restart.
Comments
Article is closed for comments.