ankane/searchkick · error · ArgumentError
Unknown quantization: #{quantization}
Error message
Unknown quantization: #{quantization} What it means
On Elasticsearch, quantization is expressed through the dense-vector field `type` suffix: `int8_hnsw`, `int4_hnsw`, or `bbq_hnsw` (and plain `hnsw` when unquantized). The case statement accepts only `"int8"`, `"int4"`, `"bbq"`, or `nil`; any other quantization value has no mapping type, so searchkick raises `ArgumentError` at mapping-build time.
Source
Thrown at lib/searchkick/index_options.rb:502
case distance
when "cosine"
"cosine"
when "euclidean"
"l2_norm"
when "inner_product"
"max_inner_product"
else
raise ArgumentError, "Unknown distance: #{distance}"
end
type =
case quantization
when "int8", "int4", "bbq"
"#{quantization}_hnsw"
when nil
"hnsw"
else
raise ArgumentError, "Unknown quantization: #{quantization}"
end
vector_index_options = knn_options.slice(:m, :ef_construction)
vector_options[:index_options] = {type: type}.merge(vector_index_options)
end
mapping[field.to_s] = vector_options
end
end
if options[:inheritance]
mapping[:type] = keyword_mapping
end
routing = {}
if options[:routing]
routing = {required: true}
unless options[:routing] == trueView on GitHub (pinned to 93e901a75b)
Solutions
- Use `quantization: "int8"`, `"int4"`, or `"bbq"` — searchkick appends `_hnsw` itself.
- Omit `quantization` entirely for full-precision HNSW.
- Verify the ES version supports the type (bbq_hnsw needs ES 8.15+); otherwise pick int8/int4.
- Reindex after the change.
Example fix
# before
searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8_hnsw"}}
# => ArgumentError: Unknown quantization: int8_hnsw
# after
searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8"}} Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_QUANTIZATION = %w[int8 int4 bbq].freeze
quant = "int8"
raise ArgumentError, "unsupported quantization #{quant}" unless SUPPORTED_QUANTIZATION.include?(quant)
class Product < ApplicationRecord
searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: quant}}
end Type guard
def valid_knn_quantization?(quant) quant.nil? || %w[int8 int4 bbq].include?(quant) end
Prevention
- Use the abstract values (int8/int4/bbq); searchkick appends `_hnsw` itself.
- Verify your ES server version supports the resulting type (bbq needs 8.15+).
- Keep quantization out of configs that run against OpenSearch.
When it happens
Trigger: `searchkick knn: {embedding: {dimensions: 768, distance: "cosine", quantization: "int8_hnsw"}}` (passing the raw ES type instead of the abstract value), or `quantization: "float8"`, `"binary"`, or `:int8` (symbol) on Elasticsearch, then reindex.
Common situations: Copying `int8_hnsw`/`int4_hnsw` straight from Elasticsearch mapping docs into the searchkick option; using a vendor's or blog's quantization name that searchkick doesn't abstract; assuming symbols and strings are interchangeable here.
Related errors
- Quantization not supported yet for OpenSearch
- The `elasticsearch` gem must be 8+
- Use Searchkick.search to search multiple models
- Redis not configured
- Could not find class: #{class_name}
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/17b1bfe60de6bfe9.
Report an issue: GitHub.