You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
.Net: Bug: .NET api-key header not sent - OpenAIChatCompletion not working with Azure AI Foundry deployments #10455
Describe the bug api-key header is not being sent when using the AddOpenAIChatCompletion Kernel extensions. Instead an Authorization: Bearer * header is being sent which does not work with Azure AI Foundry deployments - they require an api-key header.
To Reproduce
Steps to reproduce the behavior:
Register an OpenAI chat client:
services.AddOpenAIChatCompletion(
modelId: modelId,
serviceId: modelId,
openAIClient: new OpenAIClient(
credential: new ApiKeyCredential(
apiKey
),
options: new OpenAIClientOptions
{
Endpoint = new Uri(endpoint)
}
)
);
Obtain it and send a request:
var chatModel = _semanticKernel.GetRequiredService<IChatCompletionService>(chatModelInfo.ModelId);
var response = await chatModel.GetChatMessageContentAsync(
chatHistory: _chatHistory,
kernel: _Kernel);
The request will fail with a 401 Unauthorized
Expected behavior api-key header should be sent
Platform
Language: C#
Source: v. 1.3.6
AI model: Phi-3-small-8k-instruct
Additional context
Obviously it can be worked around with a custom HTTP client that's sending the correct header, but this being a Microsoft-supported package it should integrate with Microsoft products seamlessly.
changed the title [-]Bug: .NET api-key header not sent - OpenAIChatCompletion not working with Azure AI Foundry deployments[/-][+].Net: Bug: .NET api-key header not sent - OpenAIChatCompletion not working with Azure AI Foundry deployments[/+]on Feb 8, 2025
it generates a different URL from my inference endpoint - https://.services.ai.azure.com/models/openai/deployments/Phi-3-small-8k-instruct/chat/completions?api-version=2024-10-01-preview
With AddOpenAIChatCompletion the following endpoint is generated: https://.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview which works if requested with the api-key header
I tried searching for documentation, but can't find anything that describes the usages of these extension methods and their overloads.
Obviously it can be worked around with a custom HTTP client that's sending the correct header, but this being a Microsoft-supported package it should integrate with Microsoft products seamlessly.
I agree. I think we can provide a fix on Semantic Kernel level, but if we do that, it still won't work for developers who directly use OpenAI SDK. Maybe it would be better to fix it on underlying SDK level, so more developers can benefit from it.
It looks to me like it should be fixed on the underlying level as well. In the mean time maybe it's a good idea for a reference to be added on how the issue can be worked around or at least to be pointed out that it's possible for a discrepancy to arise.
Obviously it can be worked around with a custom HTTP client that's sending the correct header, but this being a Microsoft-supported package it should integrate with Microsoft products seamlessly.
Now as I more think about it, taking into account that it's OpenAIClient, we can't really update it on OpenAI .NET SDK level, since underlying SDK shouldn't be aware of Azure AI Foundry or any other OpenAI-compatible endpoints and their authentication mechanisms. That's usually the case where custom HTTP client can fix this.
In scope of this issue, we will add an example how to use OpenAI connector with Azure AI Foundry deployments.
It makes sense, in my mind actually AzureOpenAI client was the correct client to use.
It would be good to note in the documentation which client can be used with which Azure deployment.
Of course, you are right that OpenAI client should be agnostic to the specific model deployment as long as it has a compatible interface.
I think you can link Azure AI Foundry deployments like this:
var builder = Kernel.CreateBuilder();
var uri = new Uri(_azureOpenaiConfig.Endpoint);
AzureKeyCredential credential = new(_azureOpenaiConfig.API_KEY);
var client = new ChatCompletionsClient(uri, credential, new AzureAIInferenceClientOptions());
builder.AddAzureAIInferenceChatCompletion(_azureOpenaiConfig.DeploymentName, client);
_kernel = builder.Build();
_chatService = client.AsChatClient(_azureOpenaiConfig.DeploymentName).AsChatCompletionService();
I think you can link Azure AI Foundry deployments like this:
var builder = Kernel.CreateBuilder();
var uri = new Uri(_azureOpenaiConfig.Endpoint);
AzureKeyCredential credential = new(_azureOpenaiConfig.API_KEY);
var client = new ChatCompletionsClient(uri, credential, new AzureAIInferenceClientOptions());
builder.AddAzureAIInferenceChatCompletion(_azureOpenaiConfig.DeploymentName, client);
_kernel = builder.Build();
_chatService = client.AsChatClient(_azureOpenaiConfig.DeploymentName).AsChatCompletionService();
This allowed me to connect to the Foundry AI service. But, when I try to use tools I get the following error
Value error, Currently only named tools are supported. {"error":{"code":"Bad Request","message":"{\"object\":\"error\",\"message\":\"[{'type': 'value_error', 'loc': ('body',), 'msg': 'Value error, Currently only named tools are supported.', 'input': {'messages': [{'role': 'user', 'content': 'How many days until Christmas? Explain your thinking.'}], 'max_tokens': 4096, 'tools': [{'type': 'function', 'function': {'name': 'TimeInformation_GetCurrentUtcTime', 'description': 'Retrieves the current time in UTC.', 'parameters': {'type': 'object', 'required': [], 'properties': {}}}}, {'type': 'function', 'function': {'name': 'WidgetFactory_CreateWidget', 'description': 'Creates a new widget of the specified type and colors', 'parameters': {'type': 'object', 'required': ['widgetType', 'widgetColor'], 'properties': {'widgetType': {'description': 'The type of widget to be created', 'type': 'string', 'enum': ['Useful', 'Decorative']}, 'widgetColor': {'description': 'The colors of the widget to be created', 'type': 'string', 'enum': ['Red', 'Green', 'Blue']}}}}}], 'tool_choice': 'auto', 'model': 'Meta-Llama-3.1-8B-Instruct', 'stream_options': None}, 'ctx': {'error': ValueError('Currently only named tools are supported.')}}]\",\"type\":\"BadRequestError\",\"param\":null,\"code\":400}","status":400}}
var client = new ChatCompletionsClient(
new Uri(_azureOpenaiConfig.Endpoint),
new AzureKeyCredential(_azureOpenaiConfig.API_KEY),
new AzureAIInferenceClientOptions()
);
var result = await _chatService.GetChatMessageContentAsync(
new ChatHistory("How many moons does Jupiter have?"),
new AzureAIInferencePromptExecutionSettings
{
Temperature = 0.7f,
MaxTokens = 800
},
kernel: _kernel
);
Following up on the discussion to provide an official reference on using the OpenAI connector with Azure AI Foundry deployments requiring an api-key header, I have submitted a pull request adding the recommended DelegatingHandler pattern to the ChatCompletion samples:
In dotnet/samples/Concepts/ChatCompletion/Connectors_CustomHttpClient.cs:
Added UseCustomHttpClientWithApiKeyHeaderForAzureAIFoundry() demonstrating how to connect to Azure AI Foundry model endpoints (e.g. Phi-3, Mistral) on https://<resource>.services.ai.azure.com/models.
Implemented AzureAIFoundryApiKeyHandler : DelegatingHandler which automatically injects the required api-key header without modifying the underlying protocol-agnostic OpenAI client.
On the DelegatingHandler approach in #14609 — worth also stripping the SDK's own Authorization: Bearer header there, not just adding api-key, in case a gateway rejects requests carrying both. Also, the sample's hardcoded api-version (2024-05-01-preview) seems likely to go stale as Foundry's models endpoint updates — might be safer exposed as a constructor parameter.
Activity
[-]Bug: .NET api-key header not sent - OpenAIChatCompletion not working with Azure AI Foundry deployments[/-][+].Net: Bug: .NET api-key header not sent - OpenAIChatCompletion not working with Azure AI Foundry deployments[/+]py6080 commentedon Feb 8, 2025
Also tried
AddAzureOpenAIChatCompletion. While it sends the correctapi-keyheaderRequest headers:
it generates a different URL from my inference endpoint - https://.services.ai.azure.com/models/openai/deployments/Phi-3-small-8k-instruct/chat/completions?api-version=2024-10-01-preview
With
AddOpenAIChatCompletionthe following endpoint is generated: https://.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview which works if requested with the api-key headerI tried searching for documentation, but can't find anything that describes the usages of these extension methods and their overloads.
py6080 commentedon Feb 8, 2025
A
serverlessPhi-3-small-8k-instruct deployment works out-of-the-box with this experimental extension method(extension) IServiceCollection IServiceCollection.AddOpenAIChatCompletion(string modelId, Uri endpoint, [string? apiKey = null], [string? orgId = null], [string? serviceId = null]) (+ 2 overloads)the serverless deployment expects an
Authorizationheaderdmytrostruk commentedon Feb 9, 2025
py6080 Thanks for reporting this issue!
I agree. I think we can provide a fix on Semantic Kernel level, but if we do that, it still won't work for developers who directly use OpenAI SDK. Maybe it would be better to fix it on underlying SDK level, so more developers can benefit from it.
py6080 commentedon Feb 11, 2025
It looks to me like it should be fixed on the underlying level as well. In the mean time maybe it's a good idea for a reference to be added on how the issue can be worked around or at least to be pointed out that it's possible for a discrepancy to arise.
dmytrostruk commentedon Feb 11, 2025
Now as I more think about it, taking into account that it's
OpenAIClient, we can't really update it on OpenAI .NET SDK level, since underlying SDK shouldn't be aware of Azure AI Foundry or any other OpenAI-compatible endpoints and their authentication mechanisms. That's usually the case where custom HTTP client can fix this.In scope of this issue, we will add an example how to use OpenAI connector with Azure AI Foundry deployments.
py6080 commentedon Feb 14, 2025
It makes sense, in my mind actually AzureOpenAI client was the correct client to use.
It would be good to note in the documentation which client can be used with which Azure deployment.
Of course, you are right that OpenAI client should be agnostic to the specific model deployment as long as it has a compatible interface.
jiangweifang commentedon Feb 24, 2025
I think you can link Azure AI Foundry deployments like this:
You may need to reference the following NuGet packages:
MarkWard0110 commentedon Apr 15, 2025
This allowed me to connect to the Foundry AI service. But, when I try to use tools I get the following error
Value error, Currently only named tools are supported.{"error":{"code":"Bad Request","message":"{\"object\":\"error\",\"message\":\"[{'type': 'value_error', 'loc': ('body',), 'msg': 'Value error, Currently only named tools are supported.', 'input': {'messages': [{'role': 'user', 'content': 'How many days until Christmas? Explain your thinking.'}], 'max_tokens': 4096, 'tools': [{'type': 'function', 'function': {'name': 'TimeInformation_GetCurrentUtcTime', 'description': 'Retrieves the current time in UTC.', 'parameters': {'type': 'object', 'required': [], 'properties': {}}}}, {'type': 'function', 'function': {'name': 'WidgetFactory_CreateWidget', 'description': 'Creates a new widget of the specified type and colors', 'parameters': {'type': 'object', 'required': ['widgetType', 'widgetColor'], 'properties': {'widgetType': {'description': 'The type of widget to be created', 'type': 'string', 'enum': ['Useful', 'Decorative']}, 'widgetColor': {'description': 'The colors of the widget to be created', 'type': 'string', 'enum': ['Red', 'Green', 'Blue']}}}}}], 'tool_choice': 'auto', 'model': 'Meta-Llama-3.1-8B-Instruct', 'stream_options': None}, 'ctx': {'error': ValueError('Currently only named tools are supported.')}}]\",\"type\":\"BadRequestError\",\"param\":null,\"code\":400}","status":400}}qkalla commentedon Jul 18, 2025
Code (Azure AI Foundry +SK Integration .)
var builder = Kernel.CreateBuilder();
var client = new ChatCompletionsClient(
new Uri(_azureOpenaiConfig.Endpoint),
new AzureKeyCredential(_azureOpenaiConfig.API_KEY),
new AzureAIInferenceClientOptions()
);
builder.AddAzureAIInferenceChatCompletion(_azureOpenaiConfig.DeploymentName, client);
_kernel = builder.Build();
_chatService = client
.AsChatClient(_azureOpenaiConfig.DeploymentName)
.AsChatCompletionService();
Example Chat Request
var result = await _chatService.GetChatMessageContentAsync(
new ChatHistory("How many moons does Jupiter have?"),
new AzureAIInferencePromptExecutionSettings
{
Temperature = 0.7f,
MaxTokens = 800
},
kernel: _kernel
);
Console.WriteLine(result.Content);
NuGet Packages Required
github-actions commentedon Jul 18, 2026
This issue is stale because it has been open for 90 days with no activity.
dotnet: add Azure AI Foundry api-key header handler sample (microsoft…
sparkysolutions10-pixel commentedon Oct 16, 2026
Hello Dmytro Struk (@dmytrostruk) and Semantic Kernel Team! 👋
Following up on the discussion to provide an official reference on using the OpenAI connector with Azure AI Foundry deployments requiring an
api-keyheader, I have submitted a pull request adding the recommendedDelegatingHandlerpattern to the ChatCompletion samples:👉 Pull Request: #14609
🛠️ What is Added:
dotnet/samples/Concepts/ChatCompletion/Connectors_CustomHttpClient.cs:UseCustomHttpClientWithApiKeyHeaderForAzureAIFoundry()demonstrating how to connect to Azure AI Foundry model endpoints (e.g. Phi-3, Mistral) onhttps://<resource>.services.ai.azure.com/models.AzureAIFoundryApiKeyHandler : DelegatingHandlerwhich automatically injects the requiredapi-keyheader without modifying the underlying protocol-agnostic OpenAI client.license/cla: SUCCESS,team_check: SUCCESS,prepare_pr: SUCCESS,add_label: SUCCESS,Issue/PR: add title prefix: SUCCESS).Looking forward to your review! 🙏
dotnet: add api-version query injection and isolated recording tests (m…
heitoroliveiranet commentedon Oct 22, 2026
On the DelegatingHandler approach in #14609 — worth also stripping the SDK's own
Authorization: Bearerheader there, not just addingapi-key, in case a gateway rejects requests carrying both. Also, the sample's hardcoded api-version (2024-05-01-preview) seems likely to go stale as Foundry's models endpoint updates — might be safer exposed as a constructor parameter.