When enabling VNet integration on an Azure Function App to communicate with outbound internal services over private endpoints, an HTTP 502 Bad Gateway or HTTP 504 Gateway Timeout error occurs. If we disable VNet integration, the function app starts working normally.
Here is a diagram of our configuration:
In the logs, we see the following:
2022-10-14T15:04:59.443 [Information] Host initialized (1052ms)
2022-10-14T15:04:59.458 [Information] Host started (1107ms)
2022-10-14T15:04:59.459 [Information] Job host started
2022-10-14T15:04:59.500 [Debug] Debug file watch initialized.
2022-10-14T15:04:59.511 [Debug] Diagnostic file watch initialized.
2022-10-14T15:04:59.512 [Debug] Hosting started
2022-10-14T15:05:02.400 [Error] Unhandled exception. System.IO.IOException: The request was aborted.
2022-10-14T15:05:02.413 [Error] ---> System.Net.Http.Http2ConnectionException: The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1).
2022-10-14T15:05:02.418 [Error] at System.Net.Http.Http2Connection.ThrowProtocolError(Http2ProtocolErrorCode errorCode)
2022-10-14T15:05:02.425 [Information] at System.Net.Http.Http2Connection.ReadFrameAsync(Boolean initialFrame)
2022-10-14T15:05:02.425 [Information] at System.Net.Http.Http2Connection.ProcessIncomingFramesAsync()
2022-10-14T15:05:02.425 [Information] --- End of inner exception stack trace ---
2022-10-14T15:05:02.425 [Information] at System.Net.Http.Http2Connection.ThrowRequestAborted(Exception innerException)
2022-10-14T15:05:02.425 [Information] at System.Net.Http.Http2Connection.Http2Stream.SendDataAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken)
2022-10-14T15:05:02.425 [Information] at Grpc.Net.Client.StreamExtensions.WriteMessageAsync[TMessage](Stream stream, GrpcCall call, TMessage message, Action`2 serializer, CallOptions callOptions)
2022-10-14T15:05:02.425 [Information] at Grpc.Net.Client.Internal.HttpContentClientStreamWriter`2.WriteAsyncCore[TState](Func`5 writeFunc, TState state)
2022-10-14T15:05:02.425 [Information] at Microsoft.Azure.Functions.Worker.GrpcWorker.SendStartStreamMessageAsync(IClientStreamWriter`1 requestStream) in D:\a\1\s\src\DotNetWorker.Grpc\GrpcWorker.cs:line 84
2022-10-14T15:05:02.426 [Information] at Microsoft.Azure.Functions.Worker.GrpcWorker.StartAsync(CancellationToken token) in D:\a\1\s\src\DotNetWorker.Grpc\GrpcWorker.cs:line 61
2022-10-14T15:05:02.426 [Information] at Microsoft.Azure.Functions.Worker.WorkerHostedService.StartAsync(CancellationToken cancellationToken) in D:\a\1\s\src\DotNetWorker.Core\WorkerHostedService.cs:line 25
2022-10-14T15:05:02.426 [Information] at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
2022-10-14T15:05:02.426 [Information] at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
2022-10-14T15:05:02.426 [Information] at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
2022-10-14T15:05:02.426 [Information] at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
2022-10-14T15:05:02.426 [Information] at MyCompany.MyApp.Api.Program.Main() in /home/vsts/work/1/s/src/Api/Program.cs:line 14
2022-10-14T15:05:02.681 [Debug] Handling WorkerErrorEvent for runtime:dotnet-isolated, workerId:dotnet-isolated. Failed with: Microsoft.Azure.WebJobs.Script.Workers.WorkerProcessExitException: dotnet exited with code 134 (0x86)
---> System.Exception: Unhandled exception. System.IO.IOException: The request was aborted., ---> System.Net.Http.Http2ConnectionException: The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1)., at System.Net.Http.Http2Connection.ThrowProtocolError(Http2ProtocolErrorCode errorCode)
--- End of inner exception stack trace ---
2022-10-14T15:05:02.681 [Debug] Attempting to dispose webhost or jobhost channel for workerId: '6778e415-98a9-4167-8bf6-582416320e64', runtime: 'dotnet-isolated'
2022-10-14T15:05:02.681 [Debug] Disposing language worker channel with id:6778e415-98a9-4167-8bf6-582416320e64
What can cause this behavior? We have tried using the latest .NET Framework. There are also custom DNS servers and route tables configured in this environment, but we leverage the same infrastructure we use for all other private endpoint configurations, which work without issues.