The Error
Your .NET application performs a vector search against Azure AI Search and receives:
Azure.RequestFailedException: The dimensions of the vector field 'embedding' do not match the dimensions of the query vector.
Status: 400 (Bad Request)
ErrorCode: InvalidRequestParameter
This is a configuration mismatch, not a transient failure. The index schema defines a specific vector dimension when the index is created. Azure AI Search rejects any query vector whose dimension differs from that configured value — and it rejects any document vector during indexing too.
Root Cause: Embedding Model Dimensions
Different Azure OpenAI embedding models produce different-length vectors, and some models allow you to reduce dimensions at request time. If the dimension you use at query time does not match the dimension stored in the index, you get this error.
| Model | Default Dimensions | Adjustable? | Range |
|---|---|---|---|
| text-embedding-ada-002 | 1536 | No | Fixed |
| text-embedding-3-small | 1536 | Yes | 256–1536 |
| text-embedding-3-large | 3072 | Yes | 256–3072 |
The dimension mismatch usually happens in one of these scenarios:
- You indexed documents with
text-embedding-ada-002(1536 dims) but then switched totext-embedding-3-large(3072 dims) for queries without recreating the index - You used
EmbeddingGenerationOptions { Dimensions = 512 }during indexing but forgot that option at query time, getting 1536 dims instead - You created the index schema manually with the wrong dimension integer (e.g., 768 instead of 1536)
For a complete guide on building a vector search pipeline, the Vector Database Comparison for .NET Developers university article covers dimension tradeoffs across different vector stores.
Fix 1: Identify and Correct Field Dimensions
Check your current index definition first. If you built the index with FieldBuilder, the dimension comes from the [VectorSearchField] attribute on your model class. If you built it manually, check the VectorSearchField constructor call.
Here is how to create an index with explicitly correct dimensions:
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
var index = new SearchIndex("articles")
{
Fields =
{
new SimpleField("id", SearchFieldDataType.String) { IsKey = true },
new SearchableField("title"),
new SearchableField("content"),
new VectorSearchField("embedding", dimensions: 1536, vectorSearchProfileName: "default-profile")
// ^^^^ Must match your embedding model's output dimension
},
VectorSearch = new VectorSearch
{
Profiles =
{
new VectorSearchProfile("default-profile", "default-algorithm")
},
Algorithms =
{
new HnswAlgorithmConfiguration("default-algorithm")
}
}
};
var indexClient = new SearchIndexClient(
new Uri(config["AzureSearch:Endpoint"]!),
new AzureKeyCredential(config["AzureSearch:AdminKey"]!));
await indexClient.CreateOrUpdateIndexAsync(index);
If you use model-attribute-based field building, apply the dimension to the attribute:
using Azure.Search.Documents.Indexes;
public class ArticleDocument
{
[SimpleField(IsKey = true)]
public string Id { get; set; } = "";
[SearchableField]
public string Title { get; set; } = "";
[SearchableField]
public string Content { get; set; } = "";
[VectorSearchField(VectorSearchDimensions = 1536, VectorSearchProfileName = "default-profile")]
public IReadOnlyList<float>? Embedding { get; set; }
}
Fix 2: Use the Correct Field Type — Collection(Edm.Single)
Azure AI Search vector fields must use single-precision floating point, which maps to Collection(Edm.Single). Using double-precision (Collection(Edm.Double)) causes a type mismatch error that looks similar to the dimension mismatch.
When you use the VectorSearchField class from Azure.Search.Documents, the correct type is applied automatically. Problems arise when developers define the field as a raw SearchField or when reading index definitions from JSON:
// ❌ Wrong — manually specifying the wrong type
new SearchField("embedding", SearchFieldDataType.Collection(SearchFieldDataType.Double))
// ✅ Correct — VectorSearchField always uses Collection(Edm.Single) automatically
new VectorSearchField("embedding", dimensions: 1536, vectorSearchProfileName: "default-profile")
If you defined your index in the Azure portal or via REST API JSON, verify the field type is Collection(Edm.Single) and not Collection(Edm.Double).
Fix 3: Validate Embedding Dimensions Before Indexing
Add a dimension check to your indexing pipeline so mismatches fail fast at startup rather than during production queries. The Vector.Length property on the embedding result gives you the actual output dimension:
using Azure.AI.OpenAI;
using OpenAI.Embeddings;
var embeddingClient = azureOpenAIClient.GetEmbeddingClient("text-embedding-3-small");
// Generate a single test embedding to verify the output dimension
var testResult = await embeddingClient.GenerateEmbeddingAsync("dimension check");
var actualDimension = testResult.Value.Vector.Length;
const int expectedDimension = 1536; // Must match your index definition
if (actualDimension != expectedDimension)
{
throw new InvalidOperationException(
$"Embedding dimension mismatch: index expects {expectedDimension}, " +
$"model produces {actualDimension}. Recreate the index or adjust EmbeddingGenerationOptions.Dimensions.");
}
For models that support dimension reduction, pass the same EmbeddingGenerationOptions at both indexing and query time:
// Use reduced dimensions — pass this options object everywhere
var embeddingOptions = new EmbeddingGenerationOptions { Dimensions = 512 };
// At indexing time
var indexEmbedding = await embeddingClient.GenerateEmbeddingAsync(document.Content, embeddingOptions);
// At query time — same options, same dimension output
var queryEmbedding = await embeddingClient.GenerateEmbeddingAsync(userQuery, embeddingOptions);
Console.WriteLine($"Index embedding dimension: {indexEmbedding.Value.Vector.Length}"); // 512
Console.WriteLine($"Query embedding dimension: {queryEmbedding.Value.Vector.Length}"); // 512
Your index’s VectorSearchField must be created with dimensions: 512 to match.
Fix 4: Delete and Recreate the Index
Azure AI Search does not support in-place changes to vector field dimensions. If your current index has the wrong dimension, you must delete it and recreate it with the correct value, then re-index all documents.
// Step 1: Delete the index with incorrect dimensions
await indexClient.DeleteIndexAsync("articles");
// Step 2: Recreate with the corrected dimension
var correctedIndex = new SearchIndex("articles")
{
Fields =
{
new SimpleField("id", SearchFieldDataType.String) { IsKey = true },
new SearchableField("title"),
new SearchableField("content"),
new VectorSearchField("embedding", dimensions: 1536, vectorSearchProfileName: "default-profile")
},
VectorSearch = new VectorSearch
{
Profiles = { new VectorSearchProfile("default-profile", "default-algorithm") },
Algorithms = { new HnswAlgorithmConfiguration("default-algorithm") }
}
};
await indexClient.CreateOrUpdateIndexAsync(correctedIndex);
// Step 3: Re-embed and re-index all documents
var searchClient = indexClient.GetSearchClient("articles");
var embeddingClient = azureOpenAIClient.GetEmbeddingClient("text-embedding-3-small");
var allDocuments = await GetAllDocumentsFromStorageAsync(); // Your retrieval logic
var embeddings = await embeddingClient.GenerateEmbeddingsAsync(
allDocuments.Select(d => d.Content).ToList());
var indexBatch = allDocuments.Zip(embeddings.Value, (doc, emb) =>
{
doc.Embedding = emb.ToFloats().ToArray();
return doc;
}).ToList();
await searchClient.IndexDocumentsAsync(
IndexDocumentsBatch<ArticleDocument>.Upload(indexBatch));
For production systems where deleting the live index causes downtime, use index aliases instead (Fix 5).
Fix 5: Zero-Downtime Migration with Index Aliases
Azure AI Search index aliases let your application point to a logical name (the alias) while the physical index can be swapped underneath — giving you zero-downtime re-indexing. This is the recommended approach when your search index is serving live traffic.
The full workflow for this is also covered in the Build a Semantic Search API workshop, which shows how to structure a re-indexing pipeline end to end.
// Step 1: Your application currently uses alias "articles-current" → articles-v1
// Step 2: Create the new index with corrected dimensions
var newIndex = new SearchIndex("articles-v2")
{
Fields =
{
new SimpleField("id", SearchFieldDataType.String) { IsKey = true },
new SearchableField("title"),
new SearchableField("content"),
new VectorSearchField("embedding", dimensions: 3072, vectorSearchProfileName: "default-profile")
// New dimension for text-embedding-3-large
},
VectorSearch = new VectorSearch
{
Profiles = { new VectorSearchProfile("default-profile", "default-algorithm") },
Algorithms = { new HnswAlgorithmConfiguration("default-algorithm") }
}
};
await indexClient.CreateOrUpdateIndexAsync(newIndex);
// Step 3: Re-index all documents into articles-v2
// (articles-v1 is still live via the alias during this time)
var searchClient_v2 = indexClient.GetSearchClient("articles-v2");
await searchClient_v2.IndexDocumentsAsync(
IndexDocumentsBatch<ArticleDocument>.Upload(reembeddedDocuments));
// Step 4: Atomically point the alias to the new index
var alias = new SearchAlias("articles-current", "articles-v2");
await indexClient.CreateOrUpdateAliasAsync(alias);
// From this moment, all queries go to articles-v2
// Step 5: Delete the old index (now safe — no traffic)
await indexClient.DeleteIndexAsync("articles-v1");
Your application’s SearchClient should always be constructed against the alias name, never the versioned index name:
// ✅ Use alias — survives index recreation
var searchClient = new SearchClient(
new Uri(config["AzureSearch:Endpoint"]!),
"articles-current", // alias name
new AzureKeyCredential(config["AzureSearch:AdminKey"]!));
// ❌ Hardcoded index name — breaks on re-index
var searchClient = new SearchClient(..., "articles-v1", ...);
Embedding Model Migration Reference
When switching embedding models, every document in the index must be re-embedded with the new model. Mixing embeddings from different models in the same index produces silently wrong search results — the cosine similarity calculation is meaningless when comparing vectors from different model spaces.
| Scenario | Action Required |
|---|---|
| ada-002 → text-embedding-3-small (same 1536 dims) | Delete index, re-embed all docs, recreate |
| text-embedding-3-small → text-embedding-3-large (1536 → 3072) | Delete index, re-embed all docs, recreate |
| text-embedding-3-small at 1536 → same model at 512 | Delete index, re-embed all docs with Dimensions=512, recreate |
| Any model → same model, same dim, same options | No re-indexing needed |
Further Reading
- Azure AI Search vector field documentation
- Azure AI Search index aliases
- Azure.Search.Documents on NuGet