gRPC Connection Errors in IronPDF Azure Containers

When IronPDF is deployed inside Docker containers on Azure Container Instances or Azure App Service, gRPC communication between the application and the IronPDF engine can fail. This happens most often after a container idles or restarts, or when the gRPC channel is not configured with retry logic.

Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="failed to connect to all addresses")
Status(StatusCode="Unknown", Detail="Stream removed")

These errors occur because Azure container environments may shut down or recycle containers during idle periods. Without a retry policy on the gRPC channel, a single dropped connection causes the call to fail immediately instead of reconnecting. HTTP/2 stream closure and platform-specific channel setup mismatches can also produce these errors.

Solution

1. Set Container Restart Policy to Always

On Azure Container Instances, set the restart policy to Always. On Azure App Service, use a dedicated plan (Basic B1 or higher) rather than the Consumption plan, which scales to zero and terminates containers. For workloads that require persistent connections, Kubernetes-managed containers are a more stable option.

2. Configure gRPC Retry Logic

Choose the approach that matches your target framework.

For .NET Framework: use Grpc.Core.Channel with a JSON retry policy

using Grpc.Core;
using IronPdf.GrpcLayer;

string jsonString = @"
{
    ""methodConfig"": [
        {
            ""name"": [
                {
                    ""service"": ""ironpdfengineproto.IronPdfService""
                }
            ],
            ""retryPolicy"": {
                ""maxAttempts"": 5,
                ""initialBackoff"": ""1.0s"",
                ""maxBackoff"": ""30s"",
                ""backoffMultiplier"": 1.5,
                ""retryableStatusCodes"": [
                    ""UNAVAILABLE""
                ]
            }
        }
    ]
}";

var channel = new Channel("localhost:33350", ChannelCredentials.Insecure,
    new[]
    {
        new ChannelOption("grpc.service_config", jsonString)
    });

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
using Grpc.Core;
using IronPdf.GrpcLayer;

string jsonString = @"
{
    ""methodConfig"": [
        {
            ""name"": [
                {
                    ""service"": ""ironpdfengineproto.IronPdfService""
                }
            ],
            ""retryPolicy"": {
                ""maxAttempts"": 5,
                ""initialBackoff"": ""1.0s"",
                ""maxBackoff"": ""30s"",
                ""backoffMultiplier"": 1.5,
                ""retryableStatusCodes"": [
                    ""UNAVAILABLE""
                ]
            }
        }
    ]
}";

var channel = new Channel("localhost:33350", ChannelCredentials.Insecure,
    new[]
    {
        new ChannelOption("grpc.service_config", jsonString)
    });

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
Imports Grpc.Core
Imports IronPdf.GrpcLayer

Dim jsonString As String = "
{
    ""methodConfig"": [
        {
            ""name"": [
                {
                    ""service"": ""ironpdfengineproto.IronPdfService""
                }
            ],
            ""retryPolicy"": {
                ""maxAttempts"": 5,
                ""initialBackoff"": ""1.0s"",
                ""maxBackoff"": ""30s"",
                ""backoffMultiplier"": 1.5,
                ""retryableStatusCodes"": [
                    ""UNAVAILABLE""
                ]
            }
        }
    ]
}"

Dim channel = New Channel("localhost:33350", ChannelCredentials.Insecure,
    {
        New ChannelOption("grpc.service_config", jsonString)
    })

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.WithCustomChannel(channel)
)
$vbLabelText   $csharpLabel

For .NET Core / .NET 5+: use Grpc.Net.Client.GrpcChannel with RetryPolicy

using Grpc.Net.Client;
using Grpc.Net.Client.Configuration;
using IronPdf.GrpcLayer;
using Grpc.Core;

var retryPolicy = new RetryPolicy
{
    MaxAttempts = 5,
    InitialBackoff = TimeSpan.FromSeconds(1),
    MaxBackoff = TimeSpan.FromSeconds(30),
    BackoffMultiplier = 1.5,
    RetryableStatusCodes = { StatusCode.Unavailable }
};

var methodConfig = new MethodConfig
{
    Names = { MethodName.Default },
    RetryPolicy = retryPolicy
};

var channel = GrpcChannel.ForAddress("http://localhost:33350", new GrpcChannelOptions
{
    ServiceConfig = new ServiceConfig { MethodConfigs = { methodConfig } }
});

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
using Grpc.Net.Client;
using Grpc.Net.Client.Configuration;
using IronPdf.GrpcLayer;
using Grpc.Core;

var retryPolicy = new RetryPolicy
{
    MaxAttempts = 5,
    InitialBackoff = TimeSpan.FromSeconds(1),
    MaxBackoff = TimeSpan.FromSeconds(30),
    BackoffMultiplier = 1.5,
    RetryableStatusCodes = { StatusCode.Unavailable }
};

var methodConfig = new MethodConfig
{
    Names = { MethodName.Default },
    RetryPolicy = retryPolicy
};

var channel = GrpcChannel.ForAddress("http://localhost:33350", new GrpcChannelOptions
{
    ServiceConfig = new ServiceConfig { MethodConfigs = { methodConfig } }
});

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
Imports Grpc.Net.Client
Imports Grpc.Net.Client.Configuration
Imports IronPdf.GrpcLayer
Imports Grpc.Core

Dim retryPolicy As New RetryPolicy With {
    .MaxAttempts = 5,
    .InitialBackoff = TimeSpan.FromSeconds(1),
    .MaxBackoff = TimeSpan.FromSeconds(30),
    .BackoffMultiplier = 1.5,
    .RetryableStatusCodes = {StatusCode.Unavailable}
}

Dim methodConfig As New MethodConfig With {
    .Names = {MethodName.Default},
    .RetryPolicy = retryPolicy
}

Dim channel As GrpcChannel = GrpcChannel.ForAddress("http://localhost:33350", New GrpcChannelOptions With {
    .ServiceConfig = New ServiceConfig With {.MethodConfigs = {methodConfig}}
})

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.WithCustomChannel(channel)
)
$vbLabelText   $csharpLabel

3. Use RemoteServer for Simpler Configuration

If you do not need custom channel options, RemoteServer provides built-in retry support and is the recommended starting point for most Azure container deployments. Use this instead of .Docker() when the engine and application containers are not on the same local network. For the full connection configuration reference, see the IronPDF Engine guide.

IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.RemoteServer("http://your-container-host:33350")
);
IronPdf.Installation.ConnectToIronPdfHost(
    IronPdfConnectionConfiguration.RemoteServer("http://your-container-host:33350")
);
Imports IronPdf

IronPdf.Installation.ConnectToIronPdfHost( _
    IronPdfConnectionConfiguration.RemoteServer("http://your-container-host:33350") _
)
$vbLabelText   $csharpLabel

4. Prevent Engine Shutdown Between Requests

By default, IronPDF shuts down its engine between requests. Setting SkipShutdown to true keeps the engine process alive, which avoids reconnection overhead and reduces the chance of connection errors in long-running containers.

IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = True
$vbLabelText   $csharpLabel

Debug Tips

To get detailed gRPC diagnostic output, set the following environment variables in your Dockerfile or container configuration:

ENV GRPC_TRACE=all
ENV GRPC_VERBOSITY=DEBUG

Check cef.log and IronSoftware.log for additional details about connection failures. To learn how to retrieve log files from Azure, see Azure Log Files.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More
Ready to Get Started?
Nuget Downloads 19,345,590 | Version: 2026.6 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast? PM > Install-Package IronPdf
run a sample watch your HTML become a PDF.