Developers attempting to use PdfSharp on Linux or macOS frequently encounter font resolution failures, GDI+ dependency errors, and platform-specific exceptions that do not occur on Windows. The library was originally designed for .NET Framework on Windows, and while cross-platform support has improved with version 6.x and the community-maintained PdfSharpCore fork, significant gaps remain. This article examines the root causes, documents common errors, and presents an alternative approach using a library with native cross-platform support.
The Problem
PdfSharp's cross-platform compatibility issues stem from two fundamental architectural decisions: its historical dependency on GDI+ for graphics operations and its reliance on Windows-specific font resolution mechanisms.
The original PdfSharp library used System.Drawing.Common for image handling and graphics operations. On Windows, System.Drawing.Common leverages GDI+, which is part of the operating system. On Linux and macOS, System.Drawing.Common either requires libgdiplus (an unmaintained Mono project with known memory leaks) or fails outright with platform exceptions.
Version 6.x of PdfSharp introduced a "Core" build that removed the GDI+ dependency, but introduced a new problem: the Core build has no built-in font resolution strategy for non-Windows platforms. On macOS specifically, no fonts are found by default. On Linux, the default font resolver may or may not find fonts depending on the distribution and configuration. This means developers must implement custom font resolvers for any cross-platform deployment.
The community-maintained PdfSharpCore fork attempted to address these issues by replacing System.Drawing dependencies with SixLabors.ImageSharp, but it has its own limitations including TTF-only font support and ongoing font resolution issues in container environments.
Error Messages and Symptoms
Developers typically encounter one of these error patterns when running PdfSharp on Linux or macOS:
System.InvalidOperationException: No appropriate font found for family name 'Arial'.
Implement IFontResolver and assign to 'GlobalFontSettings.FontResolver' to use fonts.
at PdfSharp.Drawing.XGlyphTypeface.GetOrCreateFrom(String familyName, FontResolvingOptions fontResolvingOptions)
at PdfSharp.Drawing.XFont..ctor(String familyName, Double emSize, XFontStyleEx style)
System.PlatformNotSupportedException: System.Drawing.Common is not supported on non-Windows platforms.
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at PdfSharp.Drawing.XImage.FromFile(String path)
System.DllNotFoundException: Unable to load shared library 'user32.dll' or one of its dependencies.
at MS.Win32.UnsafeNativeMethods.IntGetSystemMetrics(SM nIndex)
PdfSharpException: No Fonts installed on this device!!
at PdfSharpCore.Utils.FontResolver.ResolveFontFamily(String familyName)
Symptoms include:
- Applications that work on Windows development machines failing in Linux Docker containers
- PDF generation crashing when any text rendering is attempted on macOS
- Font substitution producing incorrect glyphs or garbled text
- Image embedding failing with platform-not-supported exceptions
- Applications requiring complex font resolver implementations for basic functionality
Who Is Affected
This issue impacts any deployment using PdfSharp outside of Windows environments:
Operating Systems: Ubuntu, Debian, Alpine Linux, Amazon Linux, CentOS, and all macOS versions. The problem is particularly severe on macOS where no fonts are found by default, and on Alpine Linux where many fonts are distributed in OTF format which PdfSharpCore does not support.
Framework Versions: .NET Core 3.1, .NET 5, .NET 6, .NET 7, .NET 8, and .NET 9. The Core build in PdfSharp 6.x targets modern .NET but requires manual font resolver configuration. Earlier versions (1.5x and below) have stronger GDI+ dependencies.
Use Cases: Any PDF generation requiring text rendering (which is virtually all PDF generation), containerized deployments, CI/CD pipelines running on Linux, macOS desktop applications, cloud deployments on AWS Lambda or Azure Functions.
Deployment Scenarios: Docker containers (especially multi-stage builds without font packages), Kubernetes pods, serverless functions, and any headless server environment.
Evidence from the Developer Community
The PdfSharp cross-platform compatibility issue has been reported consistently across GitHub Issues, Stack Overflow, and the official PdfSharp forums.
Timeline
| Date | Event | Source |
|---|---|---|
| 2017-01-01 | PdfSharpNetStandard issues in Linux Docker containers reported | GitHub Issues |
| 2019-11-01 | "No Fonts installed on this device" errors documented | PdfSharpCore Issues |
| 2020-03-01 | Font resolver requirements for WSL/Linux/Mac clarified | PdfSharp Documentation |
| 2022-06-01 | System.Drawing.Common deprecated for non-Windows by Microsoft | .NET 6 Release |
| 2023-01-01 | PdfSharp 6.0 preview introduces Core build without GDI+ | NuGet |
| 2024-03-01 | Font resolving issues continue in Alpine/Docker deployments | GitHub Issues |
| 2024-11-01 | PdfSharp 6.2.x documents macOS has no default font resolution | Official Docs |
| 2025-01-01 | Issues persist with font resolution in containerized environments | Community Reports |
Community Reports
"Won't work inside Linux docker container. System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. This happens because System.Drawing.dll uses native Windows API for its operations."
— Developer, PdfSharpNetStandard GitHub Issues"Everything was running fine on version 1.2.6, but since updating to 1.2.8 the default font resolver can no longer find fonts when deployed to a Linux container. No Fonts installed on this device!!"
— Developer, PdfSharpCore GitHub Issues, November 2019"No fonts will be found under Linux or MacOS when using certain properties, so you should not use these properties for portable Core applications."
— PdfSharp Official Documentation, 2024"Due to filtering clauses in the LinuxSystemFontResolver.cs, OTF fonts are not allowed to be used with PdfSharpCore - only TTF fonts are supported. This is problematic when using Docker environments with Alpine images that have many open source fonts in OTF format."
— Developer, PdfSharpCore GitHub Issues
The official documentation explicitly states: "When distributing applications that use the Core build, make sure to include a font resolver that handles all font requests your application depends on, so it can run on any computer that supports the Core build, including macOS and others."
Root Cause Analysis
The cross-platform issues stem from three distinct architectural limitations:
1. GDI+ Dependency (Legacy Builds)
PdfSharp versions prior to 6.x and the -GDI and -WPF package variants depend on System.Drawing.Common for graphics operations. Microsoft explicitly deprecated System.Drawing.Common for non-Windows platforms starting with .NET 6, recommending against its use. The documentation states: "System.Drawing requires additional libraries to be installed to use outside of Windows (libgdiplus on Linux for example) and is not officially supported in headless environments."
On Linux, System.Drawing.Common requires libgdiplus, which is unmaintained and contains memory leaks. On macOS, System.Drawing.Common is not supported at all in recent .NET versions.
2. No Cross-Platform Font Resolution Strategy
The fundamental problem with PdfSharp's Core build is architectural: "The .NET version of the Core build runs on all platforms/operating systems .NET runs on and there is no general font resolving strategy on all these platforms."
Windows has the Windows Font Manager with a standardized API to enumerate and load fonts. Linux distributions store fonts in different locations (sometimes /usr/share/fonts/truetype, sometimes elsewhere) with varying formats. macOS has Core Text framework with completely different font management. PdfSharp's Core build punts on this problem entirely, requiring developers to implement custom IFontResolver implementations.
3. TTF-Only Support in PdfSharpCore
The community fork PdfSharpCore uses SixLabors.Fonts for font handling, which improved cross-platform compatibility. However, its implementation only supports TTF fonts, not OTF fonts. Many Linux distributions and font packages distribute fonts in OTF format, creating compatibility gaps.
Attempted Workarounds
The community has developed several approaches to work around these limitations.
Workaround 1: Use the Correct Package Variant
Approach: Use the base PDFsharp package (not PDFsharp-GDI or PDFsharp-WPF) for cross-platform deployments.
<!-- Cross-platform compatible -->
<PackageReference Include="PDFsharp" Version="6.2.3" />
<!-- Windows-only - will fail on Linux/macOS -->
<!-- <PackageReference Include="PDFsharp-GDI" Version="6.2.3" /> -->
Limitations:
- Still requires implementing a custom font resolver
- Does not solve the font resolution problem, only removes the GDI+ dependency
- Image handling capabilities differ from the GDI+ version
Workaround 2: Implement a Custom Font Resolver
Approach: Create a class implementing IFontResolver to handle font requests on all platforms.
using PdfSharp.Fonts;
public class CustomFontResolver : IFontResolver
{
public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
{
// Map font family names to actual font files
string fontName = familyName.ToLower() switch
{
"arial" => isBold ? "arialbd.ttf" : "arial.ttf",
"times new roman" => isBold ? "timesbd.ttf" : "times.ttf",
_ => "arial.ttf" // Fallback
};
return new FontResolverInfo(fontName);
}
public byte[] GetFont(string faceName)
{
// Load font bytes from embedded resources or file system
string fontPath = Path.Combine(AppContext.BaseDirectory, "Fonts", faceName);
if (File.Exists(fontPath))
return File.ReadAllBytes(fontPath);
// Try embedded resource
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream($"MyApp.Fonts.{faceName}");
if (stream != null)
{
using var ms = new MemoryStream();
stream.CopyTo(ms);
return ms.ToArray();
}
throw new FileNotFoundException($"Font not found: {faceName}");
}
}
// Register the font resolver before any PDF operations
GlobalFontSettings.FontResolver = new CustomFontResolver();
Limitations:
- Requires bundling font files with the application or embedding as resources
- Must handle all font variants (regular, bold, italic, bold-italic) manually
- Font licensing requires including fonts legally
- Significant development effort for comprehensive font coverage
- Must be implemented before any XFont usage in the application
Workaround 3: Install Fonts in Docker Container
Approach: Install font packages in the Docker container at build time.
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
# Install font packages
RUN apt-get update && apt-get install -y \
fonts-liberation \
fonts-dejavu-core \
fontconfig \
&& rm -rf /var/lib/apt/lists/* \
&& fc-cache -fv
Limitations:
- Increases container image size
- Still requires custom font resolver in PdfSharp 6.x
- Font paths vary between distributions
- Alpine Linux uses different package manager and font locations
- Does not help with macOS deployments
Workaround 4: Use PdfSharpCore Fork
Approach: Use the community-maintained PdfSharpCore package which replaced GDI+ with SixLabors.ImageSharp.
<PackageReference Include="PdfSharpCore" Version="1.3.67" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
// Required registration for encoding support
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Limitations:
- Only supports TTF fonts, not OTF fonts
- Still has font resolution issues in containerized environments
- Not officially maintained by empira (PdfSharp maintainers)
- Feature gaps compared to official PdfSharp
- Versioning does not align with official PdfSharp releases
A Different Approach: IronPDF
For teams where implementing and maintaining custom font resolvers is not acceptable, switching to a library with native cross-platform support eliminates these issues entirely. IronPDF uses an embedded Chromium rendering engine that handles fonts, images, and rendering natively on Windows, Linux, and macOS without requiring custom resolver implementations.
Why IronPDF Avoids This Issue
IronPDF's architecture differs fundamentally from PdfSharp in how it handles fonts and rendering. Rather than depending on System.Drawing or platform-specific font APIs, IronPDF embeds a Chromium browser engine that:
- Uses Chromium's cross-platform font rendering subsystem
- Handles font discovery and loading natively on each platform
- Requires no custom font resolver implementation
- Works identically in Docker containers, serverless environments, and desktop applications
- Supports all font formats that Chromium supports (TTF, OTF, WOFF, WOFF2)
The Chromium engine manages its own font fallback chains and rendering, eliminating the need for developers to understand platform-specific font management.
Code Example
The following example demonstrates cross-platform PDF generation that works identically on Windows, Linux, and macOS without custom font resolvers:
using IronPdf;
using System;
public class CrossPlatformPdfGenerator
{
public void GeneratePdfOnAnyPlatform()
{
// IronPDF automatically configures platform-specific binaries
// No font resolver implementation required
Installation.LinuxAndDockerDependenciesAutoConfig = true;
// Create renderer - works identically on Windows, Linux, and macOS
var renderer = new ChromePdfRenderer();
// Configure rendering options
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// Generate PDF with various fonts - Chromium handles font resolution
string htmlContent = @"
<html>
<head>
<style>
body { font-family: Arial, Helvetica, sans-serif; }
h1 { font-family: 'Times New Roman', Times, serif; color: #2c3e50; }
.mono { font-family: 'Courier New', Courier, monospace; }
.content { padding: 20px; line-height: 1.6; }
</style>
</head>
<body>
<div class='content'>
<h1>Cross-Platform Document</h1>
<p>This text renders in Arial on all platforms.</p>
<p class='mono'>Monospace text for code examples.</p>
<p><strong>Bold text</strong> and <em>italic text</em> work automatically.</p>
</div>
</body>
</html>";
using (var pdf = renderer.RenderHtmlAsPdf(htmlContent))
{
pdf.SaveAs("cross-platform-document.pdf");
Console.WriteLine($"PDF generated on {Environment.OSVersion.Platform}");
}
}
public void GeneratePdfInDockerContainer()
{
// This same code works in Docker without font package installation
// or custom font resolver implementation
var renderer = new ChromePdfRenderer();
// Enable CSS print media queries for better PDF output
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
// Render a complete webpage including all fonts and images
using (var pdf = renderer.RenderUrlAsPdf("https://example.com"))
{
// Convert to images for thumbnail generation
var images = pdf.ToPngImages("page_{0}.png");
Console.WriteLine($"Generated {images.Length} page images");
pdf.SaveAs("webpage-capture.pdf");
}
}
}
Key points about this code:
- No
IFontResolverimplementation required - No font file bundling or embedding necessary
-
LinuxAndDockerDependenciesAutoConfighandles platform setup automatically - Chromium resolves and renders fonts natively on each platform
- Font fallback chains (Arial -> Helvetica -> sans-serif) work as expected
- Image operations work without SixLabors.ImageSharp or System.Drawing dependencies
Docker Deployment
Unlike PdfSharp, IronPDF Docker deployments do not require font package installation:
FROM mcr.microsoft.com/dotnet/aspnet:8.0
# No font packages required - IronPDF uses embedded Chromium
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]
API Reference
For details on cross-platform deployment:
- ChromePdfRenderer - Main rendering class
- Docker and Linux Deployment - Container configuration guide
- macOS Support - macOS-specific documentation
- Azure Functions Guide - Serverless deployment
Migration Considerations
Licensing
IronPDF is commercial software with per-developer licensing. A free trial is available for evaluation. Teams should evaluate IronPDF's licensing model against their deployment requirements before committing to migration.
API Differences
The APIs between PdfSharp and IronPDF differ significantly in approach:
- PdfSharp uses low-level PDF primitives (
XGraphics,XFont,XBrush); IronPDF primarily uses HTML/CSS rendering - PdfSharp requires manual layout and positioning; IronPDF leverages Chromium's layout engine
- PdfSharp document manipulation uses
PdfDocument; IronPDF usesPdfDocumentbut with different APIs - For programmatic drawing, PdfSharp may be more suitable; for document generation from HTML, IronPDF is more direct
Migration effort depends heavily on whether your codebase generates PDFs programmatically or from HTML templates.
What You Gain
- Consistent behavior on Windows, Linux, and macOS without custom font resolver
- Docker containers that work without font package installation
- No platform-specific code paths for font handling
- Chromium's font rendering quality and fallback behavior
- Support for all web font formats (TTF, OTF, WOFF, WOFF2)
What to Consider
- Commercial licensing cost vs PdfSharp's MIT license
- Different rendering approach (HTML-centric vs programmatic drawing)
- Larger deployment footprint due to embedded Chromium
- Learning curve for teams experienced with PdfSharp's drawing API
Conclusion
PdfSharp's cross-platform limitations stem from architectural decisions around font resolution and graphics dependencies. While the Core build removed GDI+ dependencies, it requires developers to implement custom font resolvers for Linux and macOS deployments. For teams requiring reliable cross-platform PDF generation without platform-specific font handling code, using a library with native cross-platform support eliminates the root cause rather than working around it.
Jacob Mellor leads technical development at Iron Software and has 25+ years of experience building developer tools.
References
- PdfSharp Font Resolving Documentation{:rel="nofollow"} - Official documentation on font resolution requirements
- PdfSharpCore GitHub: No Fonts Installed Issue #125{:rel="nofollow"} - Font resolution failures in Linux containers
- PdfSharpCore GitHub: Linux Container Font Issue #406{:rel="nofollow"} - Container deployment problems
- PdfSharp Forum: System.Drawing.Common Not Supported{:rel="nofollow"} - GDI+ exception discussions
- PdfSharpNetStandard: Linux Docker Issue #6{:rel="nofollow"} - System.Drawing failures in containers
- PdfSharp Choose Version Documentation{:rel="nofollow"} - Package selection guidance
- PdfSharp .NET Framework Support{:rel="nofollow"} - Platform compatibility documentation
- PdfSharpCore GitHub: TTF Only Font Support #327{:rel="nofollow"} - OTF font limitation
- PdfSharp GitHub: Font Resolution Issue #20{:rel="nofollow"} - Segoe UI font not found regression
- PdfSharp Forum: Fonts Not Resolved on Docker and Alpine{:rel="nofollow"} - Alpine Linux font issues
For IronPDF documentation and tutorials, visit ironpdf.com.
Top comments (0)