Developers deploying QuestPDF to Azure App Service on Linux encounter InitializationException errors about missing SkiaSharp dependencies. Whether you are configuring QuestPDF Azure Functions, setting up QuestPDF Azure App Service, or trying to run QuestPDF Docker Azure containers, the library fails with cryptic messages about native dependencies. The official documentation lacks working Azure or AWS deployment examples. With 13 upvotes and ongoing community frustration, this remains one of the most common deployment blockers. This article documents the issue and examines alternatives with documented cloud deployment paths.
The Problem
QuestPDF depends on SkiaSharp for rendering, which requires native libraries that vary by operating system. Azure App Service on Linux uses specific container images that may not include all required dependencies. When these dependencies are missing, QuestPDF throws an InitializationException at runtime.
The challenge is compounded by:
- Undocumented dependency requirements for cloud platforms
- Different base images requiring different NuGet packages
- Alpine vs Debian requiring different native asset packages
- No official examples for Azure or AWS deployment
Error Messages and Symptoms
QuestPDF.Drawing.Exceptions.InitializationException: Cannot create the PDF document using the SkiaSharp-related library.
This exception usually means that, on your operating system where you run the application, SkiaSharp-related requires installing additional dependencies. Such dependencies are available as additional nuget packages, for example *.NativeAssets.Linux.NoDependencies.
Some operating systems may require installing multiple nugets, e.g. MacOS may need both *.NativeAssets.macOS.NoDep...
Additional symptoms include:
- Application works locally on Windows or macOS but fails in Azure
- Same code works in one App Service plan but fails in another
- Docker containers that worked previously fail after base image updates
- Inconsistent behavior between deployment slots
Who Is Affected
This issue impacts cloud deployments of QuestPDF:
Platforms: Azure App Service (Linux), Azure Functions (Linux), AWS Lambda, AWS ECS, Google Cloud Run, and any containerized Linux environment.
QuestPDF Versions: 2022.12.9 through 2024.3.0 and likely current versions.
Framework Versions: .NET 6, .NET 7, .NET 8 on Linux containers.
Evidence from the Developer Community
Timeline
| Date | Event | Source |
|---|---|---|
| 2023-10-07 | Documentation request for Azure/AWS examples opened | GitHub Issue #667 |
| 2023-12-15 | Multiple developers confirm Azure deployment failures | GitHub Issue #667 |
| 2024-03-01 | Issue persists, marked partially-fixed | GitHub Issue #667 |
| 2025-03-06 | Still receiving comments about deployment issues | GitHub Issue #667 |
Community Reports
"QuestPDF treats cross-platform generally and Linux in particular as not worthy of documenting. At present, I have things to the point where I'm getting the InitializationException, but please don't just add an answer here in this thread on this particular issue. Again, to be clear, please add a working example that runs in either Azure or AWS, including all the required Linux dependencies."
— Developer, GitHub Issue #667, October 2023"Does QuestPDF text generation work out of the box on a modern vanilla Azure Alpine Linux deployment using only the documented NuGet packages?"
— Developer, GitHub Issue #667, November 2023".NET 7 running in a Linux AppService in Azure - cannot get QuestPDF to initialize."
— Developer, GitHub Issue #667, December 2023
Official Response
The QuestPDF maintainer acknowledged:
"The library already contains code recognising potential problems with native SkiaSharp and HarfbuzzSharp dependencies. The existing implementation tries to suggest what nuget packages could be missing..."
However, working Azure or AWS examples remain absent from official documentation.
Root Cause Analysis
QuestPDF's SkiaSharp dependency requires platform-specific native libraries. The complexity arises from:
-
Multiple NuGet Packages: SkiaSharp offers separate packages for different Linux distributions:
SkiaSharp.NativeAssets.LinuxSkiaSharp.NativeAssets.Linux.NoDependenciesHarfBuzzSharp.NativeAssets.Linux
-
Distribution Variance: Azure App Service Linux images vary:
- Some use Alpine Linux (requires different dependencies)
- Some use Debian-based images
- Image versions change over time
Transitive Dependency Hell: QuestPDF depends on SkiaSharp, which has its own native dependency graph. Changes to any package can break deployment.
No Official Testing: The QuestPDF project does not maintain CI/CD pipelines that test Azure or AWS deployment scenarios.
Attempted Workarounds
The following workarounds have been collected from community discussions and GitHub issues. Success varies depending on Azure region, App Service plan, and exact configuration.
Workaround 1: Add NativeAssets Packages
Approach: Explicitly add SkiaSharp native asset packages to the project.
<!-- For Debian-based Azure Linux (most common) -->
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="7.3.0" />
<!-- For Alpine-based containers -->
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="7.3.0" />
<!-- May also need: -->
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
How to determine which packages you need:
- Deploy your application
- Check the InitializationException message for hints about which library is missing
- Add the corresponding NativeAssets package
- Repeat until it works (or give up)
Limitations:
- Package versions must match exactly with QuestPDF's SkiaSharp dependency version
- Different Azure regions may use different base images
- Version drift can break previously working deployments
- Trial and error approach wastes deployment cycles
Workaround 2: Install System Dependencies via Startup Script
Approach: Use a startup script to install missing libraries.
#!/bin/bash
apt-get update && apt-get install -y libfontconfig1 libfreetype6
Limitations:
- Requires App Service startup command configuration
- Increases cold start time
- May not work on all App Service plans
- Not available in all hosting scenarios (Functions, containerized)
Workaround 3: Use a Custom Docker Image
Approach: Build a custom Docker image with all dependencies pre-installed.
# Dockerfile for QuestPDF on Azure (Debian-based)
FROM mcr.microsoft.com/dotnet/aspnet:8.0
# Install all potential dependencies that SkiaSharp might need
RUN apt-get update && apt-get install -y \
libfontconfig1 \
libfreetype6 \
libpng-dev \
libjpeg-dev \
libharfbuzz0b \
libglib2.0-0 \
libicu-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "YourApp.dll"]
For Alpine-based images (smaller but more complex):
# Dockerfile for QuestPDF on Alpine
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
RUN apk add --no-cache \
fontconfig \
freetype \
harfbuzz \
icu-libs
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "YourApp.dll"]
Limitations:
- Additional infrastructure to maintain (Docker registry, container management)
- Must update base images regularly for security patches
- Adds complexity to CI/CD pipeline
- May still fail if a new SkiaSharp version requires different dependencies
Workaround 4: Azure Functions Specific Configuration
Approach: Configure Azure Functions with explicit runtime dependencies.
// host.json
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"functionTimeout": "00:10:00"
}
<!-- Function project .csproj -->
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QuestPDF" Version="2024.3.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="7.3.0" />
</ItemGroup>
Azure Functions Application Settings:
FUNCTIONS_WORKER_RUNTIME=dotnet-isolated
WEBSITE_RUN_FROM_PACKAGE=1
Limitations:
- Cold start times increase significantly
- Consumption plan memory limits may be hit
- Premium plan required for reliable operation
- Same dependency management issues as App Service
Workaround 5: Azure Container Apps
Approach: Use Azure Container Apps instead of App Service for more control.
# azure-container-apps.yaml
name: pdf-generator
properties:
configuration:
activeRevisionsMode: single
ingress:
external: true
targetPort: 8080
template:
containers:
- name: pdf-service
image: youracr.azurecr.io/pdf-generator:latest
resources:
cpu: 1.0
memory: 2Gi
env:
- name: DOTNET_RUNNING_IN_CONTAINER
value: "true"
Limitations:
- Different pricing model
- Requires Azure Container Registry
- More infrastructure to manage
A Different Approach: IronPDF
IronPDF provides documented deployment guides for Azure, AWS, and containerized environments with officially tested configurations.
Why IronPDF Works in Cloud Environments
IronPDF's architecture differs from SkiaSharp-based libraries:
- Bundled Dependencies: IronPDF includes all necessary native libraries in the NuGet package
- Documented Cloud Deployment: Official guides exist for Azure App Service, Azure Functions, AWS Lambda, and Docker
- Tested Configurations: Each release is tested against common cloud deployment scenarios
- Single Package: No transitive dependency graph to manage
Code Example
using IronPdf;
public class AzureReportGenerator
{
public byte[] GenerateReport(ReportData data)
{
// Works in Azure App Service Linux without additional configuration
var renderer = new ChromePdfRenderer();
string html = BuildReportHtml(data);
using var pdf = renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
}
private string BuildReportHtml(ReportData data)
{
return $@"
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 40px; }}
h1 {{ color: #0078d4; }}
table {{ width: 100%; border-collapse: collapse; }}
th, td {{ padding: 12px; border: 1px solid #ddd; }}
th {{ background-color: #0078d4; color: white; }}
</style>
</head>
<body>
<h1>{data.Title}</h1>
<p>Generated: {DateTime.UtcNow:yyyy-MM-dd HH:mm} UTC</p>
<table>
<thead>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{GenerateRows(data.Items)}
</tbody>
</table>
</body>
</html>";
}
private string GenerateRows(IEnumerable<ReportItem> items)
{
return string.Join("", items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Value}</td></tr>"));
}
}
Azure App Service deployment:
<!-- .csproj - no additional native asset packages needed -->
<PackageReference Include="IronPdf" Version="*" />
Key points about this code:
- Single NuGet package reference
- Works on Azure App Service Linux out of the box
- No startup scripts or custom Docker images required
- Same code works locally and in cloud
API Reference
For cloud deployment documentation:
Migration Considerations
Licensing
- IronPDF is commercial software with perpetual licensing
- Free trial available for evaluation
- Licensing information
API Differences
- QuestPDF: Fluent C# API for layout
- IronPDF: HTML/CSS-based rendering
- Migration requires changing the document generation approach
What You Gain
- Documented cloud deployment paths
- Single NuGet package with bundled dependencies
- Works on Azure, AWS, and containerized environments without special configuration
What to Consider
- Different document generation paradigm (HTML vs fluent API)
- Commercial licensing required
- Chromium binaries increase package size
Conclusion
QuestPDF's SkiaSharp dependency creates deployment challenges on cloud platforms, with no official Azure or AWS examples in the documentation. Developers spend significant time troubleshooting native dependency issues that vary by environment. For projects targeting cloud deployment, libraries with documented cloud deployment guides and bundled dependencies reduce deployment friction.
Jacob Mellor is CTO at Iron Software, with 25+ years building developer tools.
References
- QuestPDF GitHub Issue #667{:rel="nofollow"} - Azure/AWS deployment documentation request
For the latest IronPDF documentation and tutorials, visit ironpdf.com.
Top comments (0)