ankane/searchkick · error · ArgumentError
Quantization not supported yet for OpenSearch
Error message
Quantization not supported yet for OpenSearch
What it means
In the OpenSearch branch of the knn mapping builder, quantization (`int8`/`int4`/`bbq`) is a Lucene/Elasticsearch feature; OpenSearch's `knn_vector` `method` block has no equivalent parameter. Since searchkick cannot map it, it raises `ArgumentError` whenever `quantization` is non-nil on OpenSearch, even if the distance itself is valid.
Source
Thrown at lib/searchkick/index_options.rb:463
type: "knn_vector",
dimension: knn_options[:dimensions]
}
if !distance.nil?
space_type =
case distance
when "cosine"
"cosinesimil"
when "euclidean"
"l2"
when "inner_product"
"innerproduct"
else
raise ArgumentError, "Unknown distance: #{distance}"
end
if !quantization.nil?
raise ArgumentError, "Quantization not supported yet for OpenSearch"
end
vector_options[:method] = {
name: "hnsw",
space_type: space_type,
engine: "lucene",
parameters: knn_options.slice(:m, :ef_construction)
}
end
mapping[field.to_s] = vector_options
else
vector_options = {
type: "dense_vector",
dims: knn_options[:dimensions],
index: !distance.nil?
}
View on GitHub (pinned to 93e901a75b)
Solutions
- Remove `quantization:` from the knn options when targeting OpenSearch.
- Make the option conditional on engine: `knn: {embedding: {dimensions: 768, distance: "cosine"}.merge(Searchkick.opensearch? ? {} : {quantization: "int8"})}`.
- If memory is the concern on OpenSearch, tune `m`/`ef_construction` (passed through as method parameters) or reduce `dimensions` instead.
- Switch the index to Elasticsearch if scalar quantization is a hard requirement.
Example fix
# before
searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8"}}
# OpenSearch => ArgumentError: Quantization not supported yet for OpenSearch
# after
knn_opts = {dimensions: 768, distance: "cosine"}
knn_opts[:quantization] = "int8" unless Searchkick.opensearch?
searchkick knn: {embedding: knn_opts} Defensive patterns
Strategy: validation
Validate before calling
knn = {embedding: {dimensions: 768, distance: "cosine"}}
knn.each_value { |o| o.delete(:quantization) } if Searchkick.opensearch?
class Product < ApplicationRecord
searchkick knn: knn
end Type guard
def knn_engine_compatible?(knn, opensearch:)
!opensearch || knn.all? { |_, o| o[:quantization].nil? }
end Prevention
- Branch engine-specific knn options on `Searchkick.opensearch?` in one config helper.
- Document in the model comment that quantization is ES-only so teammates don't re-add it.
- Run `Model.reindex` in a staging environment identical to production engine before deploy.
When it happens
Trigger: `searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8"}}` while `Searchkick.opensearch?` is true, then reindex. The check runs right after the distance case statement, so any valid distance plus any quantization value triggers it.
Common situations: Sharing one model config between an Elasticsearch dev environment and an OpenSearch production environment (common with Amazon OpenSearch Service); following the README's ES scalar-quantization examples on OpenSearch; enabling quantization to shrink a large embedding index without checking engine support.
Related errors
- Must specify a distance for OpenSearch
- Unknown distance: #{distance}
- Unknown quantization: #{quantization}
- The `elasticsearch` gem must be 8+
- Use Searchkick.search to search multiple models
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/31a0f9c2b62070e0.
Report an issue: GitHub.