The most downloaded sentence-embedding model in the world ships four configuration files. Each declares a maximum input length. They do not agree.

FileKeyValue
tokenizer.jsontruncation.max_length128
sentence_bert_config.jsonmax_seq_length256
tokenizer_config.jsonmodel_max_length512
config.jsonmax_position_embeddings512

Which one applies to your text is decided entirely by which library you imported. Nothing warns you, and the output is a perfectly ordinary vector either way.

Four doors into one model

These files are not redundant copies that drifted apart. Each belongs to a different layer, and each layer is a legitimate entry point that a working system might use:

  • The raw tokenizer reads tokenizer.json and truncates at 128. That file also pins padding to a fixed 128, so every output is exactly that long.
  • The sentence-transformers wrapper reads sentence_bert_config.json and truncates at 256. This is the path most tutorials use.
  • The transformers auto-tokenizer reads tokenizer_config.json and allows 512.
  • The architecture itself declares 512 positions, which is the real ceiling the weights were trained against.

The same document, embedded through two different but reasonable code paths, can be truncated at 128 tokens or at 512 — a fourfold difference determined by an import statement.

Why you will not notice

Truncation in this stack is not an error. It is the silent default: the tokenizer is instructed to truncate, so it does, returning a valid tensor without any signal that data was lost.

The result is a normal-looking 384-dimension vector. It has a plausible magnitude and sits in the expected vector space, and cosine similarity against it returns sensible numbers. There is no field on the output that says "I discarded two thirds of your input".

⚠️ This produces the nastiest kind of failure, where two documents that differ only after the cut-off point embed to nearly the same vector. A contract chunk ending "termination requires 45 days notice" and one ending "termination requires 14 days notice" are, to the index, the same passage — if the difference falls past the limit that happened to apply.

It compounds with the other default nobody reads

Chunking libraries generally measure in characters. Embedding models measure in tokens. Those are different units, and the conversion is not one-to-one.

A common default chunk size is 4,000 characters. For ordinary English prose that is roughly 750 to 800 word pieces — comfortably past 256, and past 512. So the stock chunker and the stock embedder, both used at their defaults, produce chunks the embedder cannot see the end of. Neither component is misconfigured. Each is doing exactly what it says.

You can see the size of the gap for yourself with our token counter or the tokenization visualizer, which shows where a given piece of text actually breaks.

What this does not mean

It does not mean the model is badly packaged. Every one of those four numbers is correct for the layer that reads it: 512 really is the architectural limit, 256 really is what the sentence-transformers wrapper was configured to use, and 128 really is what the bundled tokenizer state was saved with. The files are consistent with themselves; it is the ensemble that has no single answer.

It does not mean short limits are wrong either. Embedding quality on this family of models degrades well before 512 tokens, and a 256-token cap is a defensible engineering choice rather than an accident.

The takeaway is that "the model's context is 512" is not a fact about the model itself, but about a specific code path. The limit changes depending on which path you take.

What to do about it

Do not look up the limit. Measure it, once, in the exact stack you are running:

  1. Take a document you know is long — several thousand characters.
  2. Embed it, then embed only its first paragraph.
  3. Compare the two vectors. If they are nearly identical, everything after the first paragraph was discarded, and you have just found your real limit.

Then chunk in tokens rather than characters, using the tokenizer the embedder actually loads. If your chunker only speaks characters, set the size well below the token limit divided by your text's characters-per-token ratio, and verify with the test above rather than trusting the arithmetic.

And if you are debugging a retrieval system that returns confident nonsense, check this before you change the model. Silent truncation looks exactly like a model that is bad at your domain.

Where this comes from, and what will date it

All four values were read directly from the model repository's own files rather than from documentation about them: tokenizer.json, sentence_bert_config.json, tokenizer_config.json and config.json, fetched and parsed for this piece. The 128 figure includes a fixed padding length of the same size in the same file, which is why that path produces uniform-length output.

⚠️ There are two limits worth stating. We describe what the configuration files declare and which layer reads which file; we have not audited every library version, and a wrapper can override any of these at call time — an explicit max_length argument beats all four. And the character-to-token ratio in the chunking example is for ordinary English prose; code, CJK text and heavily punctuated content differ substantially, which is its own reason to measure rather than assume.

The specific numbers will date if the model is repackaged, and that is the shallow half. The durable half is structural: a model artefact is a bundle of files read by different layers, any of which may carry its own limit, and agreement between them is a convention rather than a guarantee. Any model distributed this way can develop the same disagreement.