I wrote a small C# app that uses the Microsoft Semantic Kernel nuget package that opens a console window and accepts lines of text, and submits them to the kernel/openai, and shows what the kernel returns.
It works fine at home, but when I bring the code onto my work computer it fails with the message "Unhandled exception. System.ClientModel.ClientResultException: The SSL connection could not be established" when GetStreamingChatMessageContentsAsync is called
If you run the code below, and type Hello the error is thrown (shown below)
I spoke with someone at Microsoft and he said he wasnt sure why the issue is occurring, suggesting it may possibly an issue with a reverse proxy.
Any ideas how I might get around this?
Here is the main code:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using System;
using AiPlayground;
using Microsoft.SemanticKernel.Connectors.OpenAI;
var builder = Kernel.CreateBuilder();
var modelId = "gpt-4o-mini";
var secret = @"fakesecret-fakesecret";
// Services
builder.AddOpenAIChatCompletion(modelId: modelId, apiKey: secret);
Kernel kernel = builder.Build();
var chatService= kernel.GetRequiredService<IChatCompletionService>();
var chatMessages = new ChatHistory();
chatMessages.AddSystemMessage("You are Jerry Seinfeld and you like to talk about insureds and policies");
while (true)
{
Console.Write("Prompt:");
chatMessages.AddUserMessage(Console.ReadLine());
var result = chatService.GetStreamingChatMessageContentsAsync(chatMessages,
executionSettings: new OpenAIPromptExecutionSettings
{
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
},kernel:kernel);
var fullMessage = "";
await foreach (var content in result)
{
Console.Write(content);
fullMessage += content;
}
chatMessages.AddAssistantMessage(fullMessage);
Console.WriteLine();
}
Here is the full exception:
Unhandled exception. System.ClientModel.ClientResultException: The SSL connection could not be established, see inner exception.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: RevocationStatusUnknown
at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
at System.Threading.Tasks.TaskCompletionSourceWithCancellation1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async) --- End of inner exception stack trace --- at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async) at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessCoreAsync(PipelineMessage message) at System.ClientModel.Primitives.PipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async) at System.ClientModel.Primitives.PipelineTransport.ProcessAsync(PipelineMessage message) at System.ClientModel.Primitives.PipelineTransport.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.PipelinePolicy.ProcessNextAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at System.ClientModel.Primitives.ApiKeyAuthenticationPolicy.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.PipelinePolicy.ProcessNextAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at System.ClientModel.Primitives.ClientRetryPolicy.ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex, Boolean async)
at System.ClientModel.Primitives.ClientRetryPolicy.ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex, Boolean async) at System.ClientModel.Primitives.ClientRetryPolicy.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at OpenAI.GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at OpenAI.GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at System.ClientModel.Primitives.ClientPipeline.SendAsync(PipelineMessage message) at OpenAI.ClientPipelineExtensions.ProcessMessageAsync(ClientPipeline pipeline, PipelineMessage message, RequestOptions options) at OpenAI.Chat.ChatClient.CompleteChatAsync(BinaryContent content, RequestOptions options) at OpenAI.Chat.ChatClient.<>c__DisplayClass12_0.<<CompleteChatStreamingAsync>g__sendRequestAsync|0>d.MoveNext() --- End of stack trace from previous location --- at OpenAI.Chat.InternalAsyncStreamingChatCompletionUpdateCollection.GetRawPagesAsync()+MoveNext() at OpenAI.Chat.InternalAsyncStreamingChatCompletionUpdateCollection.GetRawPagesAsync()+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult() at System.ClientModel.AsyncCollectionResult
1.GetAsyncEnumerator(CancellationToken cancellationToken)+MoveNext()
at System.ClientModel.AsyncCollectionResult1.GetAsyncEnumerator(CancellationToken cancellationToken)+MoveNext() at System.ClientModel.AsyncCollectionResult
1.GetAsyncEnumerator(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
at Microsoft.SemanticKernel.Connectors.OpenAI.ClientCore.GetStreamingChatMessageContentsAsync(String targetModel, ChatHistory chatHistory, PromptExecutionSettings executionSettings, Kernel kernel, CancellationToken cancellationToken)+MoveNext()
at Microsoft.SemanticKernel.Connectors.OpenAI.ClientCore.GetStreamingChatMessageContentsAsync(String targetModel, ChatHistory chatHistory, PromptExecutionSettings executionSettings, Kernel kernel, CancellationToken cancellationToken)+MoveNext()
at Microsoft.SemanticKernel.Connectors.OpenAI.ClientCore.GetStreamingChatMessageContentsAsync(String targetModel, ChatHistory chatHistory, PromptExecutionSettings executionSettings, Kernel kernel, CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
at Program.$(String[] args) in C:\Users\rickh\source\repos\AiPlayground\AiPlayground\Program.cs:line 40
at Program.$(String[] args) in C:\Users\rickh\source\repos\AiPlayground\AiPlayground\Program.cs:line 40
at Program.(String[] args)
I wrote a small C# app that uses the Microsoft Semantic Kernel nuget package that opens a console window and accepts lines of text, and submits them to the kernel/openai, and shows what the kernel returns.
It works fine at home, but when I bring the code onto my work computer it fails with the message "Unhandled exception. System.ClientModel.ClientResultException: The SSL connection could not be established" when GetStreamingChatMessageContentsAsync is called
If you run the code below, and type Hello the error is thrown (shown below)
I spoke with someone at Microsoft and he said he wasnt sure why the issue is occurring, suggesting it may possibly an issue with a reverse proxy.
Any ideas how I might get around this?
Here is the main code:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using System;
using AiPlayground;
using Microsoft.SemanticKernel.Connectors.OpenAI;
var builder = Kernel.CreateBuilder();
var modelId = "gpt-4o-mini";
var secret = @"fakesecret-fakesecret";
// Services
builder.AddOpenAIChatCompletion(modelId: modelId, apiKey: secret);
Kernel kernel = builder.Build();
var chatService= kernel.GetRequiredService<IChatCompletionService>();
var chatMessages = new ChatHistory();
chatMessages.AddSystemMessage("You are Jerry Seinfeld and you like to talk about insureds and policies");
while (true)
{
Console.Write("Prompt:");
chatMessages.AddUserMessage(Console.ReadLine());
var result = chatService.GetStreamingChatMessageContentsAsync(chatMessages,
executionSettings: new OpenAIPromptExecutionSettings
{
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
},kernel:kernel);
var fullMessage = "";
await foreach (var content in result)
{
Console.Write(content);
fullMessage += content;
}
chatMessages.AddAssistantMessage(fullMessage);
Console.WriteLine();
}
Here is the full exception:
Unhandled exception. System.ClientModel.ClientResultException: The SSL connection could not be established, see inner exception.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: RevocationStatusUnknown
at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
at System.Threading.Tasks.TaskCompletionSourceWithCancellation1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async) --- End of inner exception stack trace --- at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async) at System.ClientModel.Primitives.HttpClientPipelineTransport.ProcessCoreAsync(PipelineMessage message) at System.ClientModel.Primitives.PipelineTransport.ProcessSyncOrAsync(PipelineMessage message, Boolean async) at System.ClientModel.Primitives.PipelineTransport.ProcessAsync(PipelineMessage message) at System.ClientModel.Primitives.PipelineTransport.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.PipelinePolicy.ProcessNextAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at System.ClientModel.Primitives.ApiKeyAuthenticationPolicy.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at System.ClientModel.Primitives.PipelinePolicy.ProcessNextAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at System.ClientModel.Primitives.ClientRetryPolicy.ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex, Boolean async)
at System.ClientModel.Primitives.ClientRetryPolicy.ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex, Boolean async) at System.ClientModel.Primitives.ClientRetryPolicy.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at OpenAI.GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList
1 pipeline, Int32 currentIndex)
at OpenAI.GenericActionPipelinePolicy.ProcessAsync(PipelineMessage message, IReadOnlyList1 pipeline, Int32 currentIndex) at System.ClientModel.Primitives.ClientPipeline.SendAsync(PipelineMessage message) at OpenAI.ClientPipelineExtensions.ProcessMessageAsync(ClientPipeline pipeline, PipelineMessage message, RequestOptions options) at OpenAI.Chat.ChatClient.CompleteChatAsync(BinaryContent content, RequestOptions options) at OpenAI.Chat.ChatClient.<>c__DisplayClass12_0.<<CompleteChatStreamingAsync>g__sendRequestAsync|0>d.MoveNext() --- End of stack trace from previous location --- at OpenAI.Chat.InternalAsyncStreamingChatCompletionUpdateCollection.GetRawPagesAsync()+MoveNext() at OpenAI.Chat.InternalAsyncStreamingChatCompletionUpdateCollection.GetRawPagesAsync()+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult() at System.ClientModel.AsyncCollectionResult
1.GetAsyncEnumerator(CancellationToken cancellationToken)+MoveNext()
at System.ClientModel.AsyncCollectionResult1.GetAsyncEnumerator(CancellationToken cancellationToken)+MoveNext() at System.ClientModel.AsyncCollectionResult
1.GetAsyncEnumerator(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
at Microsoft.SemanticKernel.Connectors.OpenAI.ClientCore.GetStreamingChatMessageContentsAsync(String targetModel, ChatHistory chatHistory, PromptExecutionSettings executionSettings, Kernel kernel, CancellationToken cancellationToken)+MoveNext()
at Microsoft.SemanticKernel.Connectors.OpenAI.ClientCore.GetStreamingChatMessageContentsAsync(String targetModel, ChatHistory chatHistory, PromptExecutionSettings executionSettings, Kernel kernel, CancellationToken cancellationToken)+MoveNext()
at Microsoft.SemanticKernel.Connectors.OpenAI.ClientCore.GetStreamingChatMessageContentsAsync(String targetModel, ChatHistory chatHistory, PromptExecutionSettings executionSettings, Kernel kernel, CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
at Program.$(String[] args) in C:\Users\rickh\source\repos\AiPlayground\AiPlayground\Program.cs:line 40
at Program.$(String[] args) in C:\Users\rickh\source\repos\AiPlayground\AiPlayground\Program.cs:line 40
at Program.(String[] args)
That is most likely due to a proxy at work. You may be able to replicate the error at home by running a proxy such as Fiddler classic. The workaround is to use custom http client that bypass check for certificate revocation list as suggested here https://github.com/microsoft/semantic-kernel/discussions/66.
var handler = new HttpClientHandler();
handler.CheckCertificateRevocationList = false;
var httpClient = new HttpClient(handler);
Then call extension method that allows passing custom http client such as
builder.AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey, null, modelId, httpClient);
Of course, for actual production deployment you should discuss with IT dept instead of the workaround.