DEV Community

IronSoftware
IronSoftware

Posted on

PdfSharp Not Working with .NET 6, .NET 7, and .NET 8 (Issue Fixed)

Developers migrating from .NET Framework to modern .NET versions frequently encounter PdfSharp compatibility problems. The combination of Microsoft's deprecation of System.Drawing.Common, the confusion between the official PDFsharp and community PdfSharpCore forks, and breaking changes in font resolution create a challenging upgrade path. This article documents the specific errors developers encounter, their root causes, and provides a migration path to a library with native modern .NET support.

The Problem

PdfSharp compatibility issues with .NET 6, .NET 7, and .NET 8 fall into three categories: package version confusion, System.Drawing.Common deprecation, and font resolver requirements.

Developers using the older PDFsharp 1.5x series encounter immediate problems when targeting .NET 6 or later. The package was built for .NET Framework 4.x and generates compatibility warnings during restore. More critically, the GDI+ and WPF variants depend on System.Drawing.Common, which Microsoft deprecated for non-Windows platforms starting in .NET 6 and removed support entirely in .NET 7.

The official PDFsharp 6.x release addressed some of these issues by introducing a Core build without GDI+ dependencies. However, this new version introduced its own breaking change: the Core build has no default font resolution strategy and throws exceptions on non-Windows platforms unless developers implement custom IFontResolver classes.

Adding to the confusion, two forks exist with similar names: the official "PDFsharp" from empira and the community-maintained "PdfSharpCore" from Stefan Steiger. These have different namespaces, different capabilities, and different .NET version support. Developers frequently install the wrong package or encounter namespace conflicts when migrating codebases.

Error Messages and Symptoms

When using PDFsharp 1.5x with modern .NET:

NU1701: Package 'PDFsharp 1.50.5147' was restored using '.NETFramework,Version=v4.6.1,
.NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1,
.NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8, .NETFramework,Version=v4.8.1'
instead of the project target framework 'net6.0-windows7.0'. This package may not be
fully compatible with your project.
Enter fullscreen mode Exit fullscreen mode

When System.Drawing.Common is used on Linux in .NET 6:

System.TypeInitializationException: The type initializer for 'Gdip' threw an exception.
 ---> System.PlatformNotSupportedException: System.Drawing.Common is not supported
      on non-Windows platforms. See https://aka.ms/systemdrawingnonwindows for more information.
   at System.Drawing.SafeNativeMethods.Gdip.PlatformInitialize()
   at System.Drawing.SafeNativeMethods.Gdip..cctor()
Enter fullscreen mode Exit fullscreen mode

When font resolver is not configured in PDFsharp 6.x Core:

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)
Enter fullscreen mode Exit fullscreen mode

When running PDFsharp 6.x in multi-targeting projects:

System.IO.FileNotFoundException: Could not load file or assembly
'Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral,
PublicKeyToken=adb9793829ddae60' or one of its dependencies.
The system cannot find the file specified.
Enter fullscreen mode Exit fullscreen mode

Font substitution warnings when using fallback resolvers:

info: PdfSharp.Snippets.Font.FailsafeFontResolver[0]
      'Arial' bold was substituted by a SegoeWP font.
Enter fullscreen mode Exit fullscreen mode

Symptoms include:

  • Projects that compiled under .NET Framework failing after migration to .NET 6+
  • PDF generation working on Windows but crashing in Linux containers
  • Font rendering producing garbled text or missing glyphs
  • Application startup failures due to missing assembly dependencies
  • NuGet restore warnings about package compatibility

Who Is Affected

This issue impacts developers upgrading existing applications or starting new projects with PdfSharp on modern .NET:

Operating Systems: The System.Drawing.Common deprecation specifically impacts Linux and macOS deployments. Windows deployments using the GDI or WPF packages continue to work but cannot be ported to cross-platform deployment.

Framework Versions: .NET 6 introduced the System.Drawing.Common deprecation with a runtime switch workaround. .NET 7 removed the workaround entirely. .NET 8, .NET 9, and .NET 10 continue without System.Drawing.Common support on non-Windows platforms.

Use Cases: Any application using PDFsharp 1.5x that migrates to .NET 6+, containerized deployments on Linux, CI/CD pipelines running on non-Windows agents, and Azure/AWS deployments that use Linux-based hosting.

Project Types: ASP.NET Core web applications, console applications, Blazor Server and WebAssembly, MAUI applications targeting non-Windows platforms, and microservices in Docker/Kubernetes.

Evidence from the Developer Community

The PDFsharp .NET 6/7/8 compatibility issue has been documented extensively across GitHub, official forums, and developer communities.

Timeline

Date Event Source
2021-11-01 .NET 6 released with System.Drawing.Common deprecation Microsoft
2022-03-15 PDFsharp incompatibility with .NET 6 reported GitHub Issue #50
2022-11-01 .NET 7 removes System.Drawing.EnableUnixSupport switch Microsoft
2023-01-01 PDFsharp 6.0 preview released with Core build NuGet
2023-06-01 Font resolver requirements documented for Core build Official Docs
2024-02-01 Multi-targeting assembly loading issues reported GitHub Issue #257
2024-11-01 .NET 6 end of support, PDFsharp drops .NET 6 compilation target GitHub Issue #119
2025-01-01 PDFsharp 6.2.3 adds .NET 9 and .NET 10, removes .NET 6 compilation NuGet

Community Reports

"Package 'PDFsharp 1.50.5147' was restored using '.NETFramework,Version=v4.6.1...' instead of the project target framework 'net6.0-windows7.0'. This package may not be fully compatible with your project."
— GitHub Issue #50, empira/PDFsharp

"Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0' - When building the plugin with PDFsharp DLLs included, testing it in AutoCAD 2018 (net462) doesn't work while it works in AutoCAD 2025 (net8.0-windows)."
— GitHub Issue #257, empira/PDFsharp

"With version 6.0.0 it is highly recommended to supply a FontResolver for the Core build. You can try NewFontResolver, SegoeUiFontResolver, or SegoeWpFontResolver that are included with this release."
— PDFsharp Official Documentation

"Version 6.2.3 no longer compiles against .NET 6 which is out of support. The NuGet packages can still be used for applications that use .NET 6."
— PDFsharp Release Notes, November 2024

The official documentation explicitly acknowledges the complexity: "This applies to both creating new projects and to upgrading your existing projects from PDFsharp & MigraDoc 1.5 or PdfSharpCore to PDFsharp 6."

Root Cause Analysis

The .NET 6/7/8 compatibility issues stem from three interconnected factors:

1. Microsoft's System.Drawing.Common Deprecation

Microsoft made a breaking change in .NET 6 that directly impacts PDFsharp's GDI+ builds. The documentation states: "Prior to .NET 6, using the System.Drawing.Common package did not produce any compile-time warnings, and no runtime exceptions were thrown. Starting in .NET 6, the platform analyzer emits compile-time warnings when referencing code is compiled for non-Windows operating systems."

The underlying reason was technical debt: "libgdiplus is the main provider of the cross-platform implementation of System.Drawing.Common on the native side. libgdiplus is effectively a reimplementation of the parts of Windows that System.Drawing.Common depends on. That implementation makes libgdiplus a non-trivial component. It's around 30,000 lines of C code that's largely untested, and it lacks a lot of functionality."

In .NET 6, a runtime switch System.Drawing.EnableUnixSupport provided a workaround. Microsoft removed this switch in .NET 7, making the deprecation permanent.

2. PDFsharp Package Fragmentation

The PDFsharp ecosystem has multiple packages that confuse developers:

  • PDFsharp (empira) - Official package, Core build, cross-platform
  • PDFsharp-GDI (empira) - Official package, Windows-only, uses System.Drawing
  • PDFsharp-WPF (empira) - Official package, Windows-only, uses WPF
  • PdfSharpCore (ststeiger) - Community fork, uses SixLabors.ImageSharp
  • PdfSharp.NetStandard - Older fork, mostly abandoned

The official documentation notes: "PdfSharpCore is a port of an older PDFsharp version. All namespaces have been changed from 'PdfSharp' to 'PdfSharpCore'." This namespace difference means switching between packages requires updating all using statements.

3. Font Resolver Architecture Change

PDFsharp 6.x's Core build fundamentally changed how fonts work: "In the Core build, PlatformFontResolver throws an exception by default. The reason is that 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."

This was a conscious design decision. The documentation explains: "No fonts will be found under Linux or MacOS, so do not use these properties if you want to develop portable Core applications." Developers must now implement IFontResolver or use one of the built-in fallback resolvers for testing only.

Attempted Workarounds

The developer community has documented several approaches to work around these compatibility issues.

Workaround 1: Use the Correct PDFsharp 6.x Package

Approach: Upgrade to PDFsharp 6.x and select the appropriate package variant for your deployment target.

<!-- For cross-platform deployments (Linux, macOS, Windows) -->
<PackageReference Include="PDFsharp" Version="6.2.3" />

<!-- For Windows-only deployments using GDI+ graphics -->
<PackageReference Include="PDFsharp-GDI" Version="6.2.3" />

<!-- For Windows-only deployments using WPF graphics -->
<PackageReference Include="PDFsharp-WPF" Version="6.2.3" />
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Still requires font resolver configuration for Core build
  • Breaking API changes from 1.5x require code updates
  • Does not solve multi-targeting assembly resolution issues
  • .NET 6 projects must use netstandard2.0 target framework

Workaround 2: Implement Custom Font Resolver

Approach: Create an IFontResolver implementation to handle font requests on all platforms.

using PdfSharp.Fonts;
using System.Reflection;

public class EmbeddedFontResolver : IFontResolver
{
    public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
    {
        // Map requested fonts to embedded font files
        string fontFile = (familyName.ToLowerInvariant(), isBold, isItalic) switch
        {
            ("arial", false, false) => "Arial-Regular.ttf",
            ("arial", true, false) => "Arial-Bold.ttf",
            ("arial", false, true) => "Arial-Italic.ttf",
            ("arial", true, true) => "Arial-BoldItalic.ttf",
            _ => "Arial-Regular.ttf" // Fallback for unknown fonts
        };

        return new FontResolverInfo(fontFile);
    }

    public byte[] GetFont(string faceName)
    {
        // Load font from embedded resources
        var assembly = Assembly.GetExecutingAssembly();
        var resourceName = $"MyApp.Fonts.{faceName}";

        using var stream = assembly.GetManifestResourceStream(resourceName);
        if (stream == null)
            throw new FileNotFoundException($"Embedded font not found: {faceName}");

        using var memoryStream = new MemoryStream();
        stream.CopyTo(memoryStream);
        return memoryStream.ToArray();
    }
}

// Register before any PDF operations
GlobalFontSettings.FontResolver = new EmbeddedFontResolver();
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Requires bundling font files (licensing considerations for commercial fonts)
  • Must handle all font family/weight/style combinations
  • Significant development effort for comprehensive coverage
  • Cannot be changed after first use (throws "Must not change font resolver after it was once used")

Workaround 3: Use System.Drawing.EnableUnixSupport (.NET 6 Only)

Approach: For .NET 6 projects, enable the deprecated Unix support for System.Drawing.Common.

Add to runtimeconfig.template.json:

{
  "configProperties": {
    "System.Drawing.EnableUnixSupport": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Also install libgdiplus in your Linux environment:

RUN apt-get update && apt-get install -y libgdiplus
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Only works in .NET 6; the switch was removed in .NET 7
  • libgdiplus has known memory leaks and is unmaintained
  • Not a path forward for .NET 7, .NET 8, or later
  • Does not solve font resolver issues in Core build

Workaround 4: Pin to .NET Standard 2.0 Build

Approach: For multi-targeting projects, rely on the .NET Standard 2.0 compatible build.

<PropertyGroup>
    <TargetFrameworks>net6.0;net8.0;net462</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
    <!-- The netstandard2.0 target supports all these frameworks -->
    <PackageReference Include="PDFsharp" Version="6.2.3" />
</ItemGroup>
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Loses .NET 8/9/10-specific optimizations
  • Still requires dependency management for logging abstractions
  • Font resolver still required for non-Windows
  • May encounter assembly binding issues in complex projects

A Different Approach: IronPDF

For teams where managing PDFsharp's .NET version compatibility, font resolvers, and System.Drawing deprecation creates ongoing maintenance burden, switching to a library built natively for modern .NET eliminates these issues. IronPDF was designed from the ground up to support .NET 6, .NET 7, .NET 8, .NET 9, and .NET 10 with identical behavior across Windows, Linux, and macOS.

Why IronPDF Avoids This Issue

IronPDF's architecture avoids the PDFsharp compatibility problems through several design decisions:

  • No System.Drawing dependency: IronPDF uses an embedded Chromium rendering engine, not GDI+ or System.Drawing.Common
  • Native .NET 6+ support: Built to target modern .NET versions directly, not through compatibility shims
  • No font resolver required: Chromium handles font discovery and rendering natively on each platform
  • Single package: One NuGet package works across all supported .NET versions and operating systems
  • Consistent API: No different package variants with different capabilities

The Chromium engine handles fonts, images, and layout using its own cross-platform implementations rather than delegating to platform-specific graphics subsystems.

Code Example

The following example demonstrates PDF generation that works identically on .NET 6, .NET 7, .NET 8, .NET 9, and .NET 10 across all operating systems:

using IronPdf;
using System;
using System.Threading.Tasks;

public class ModernDotNetPdfGenerator
{
    public void GeneratePdfOnAnyDotNetVersion()
    {
        // IronPDF works identically on .NET 6, 7, 8, 9, and 10
        // No font resolver, no System.Drawing dependency

        var renderer = new ChromePdfRenderer();

        // Configure margins and paper size
        renderer.RenderingOptions.SetCustomPaperSizeinMilimeters(210, 297); // A4
        renderer.RenderingOptions.MarginTop = 25;
        renderer.RenderingOptions.MarginBottom = 25;

        // Enable print-friendly CSS media type
        renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;

        // Generate PDF from HTML - fonts work automatically
        string htmlContent = @"
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body {
                        font-family: 'Segoe UI', Arial, sans-serif;
                        font-size: 12pt;
                        line-height: 1.6;
                    }
                    h1 {
                        color: #1a1a2e;
                        font-size: 24pt;
                        border-bottom: 2px solid #4a4e69;
                    }
                    .highlight { background-color: #f8f9fa; padding: 10px; }
                    table {
                        width: 100%;
                        border-collapse: collapse;
                        margin: 20px 0;
                    }
                    th, td {
                        border: 1px solid #ddd;
                        padding: 12px;
                        text-align: left;
                    }
                    th { background-color: #4a4e69; color: white; }
                </style>
            </head>
            <body>
                <h1>Report Generated on " + Environment.OSVersion.Platform + @"</h1>
                <p>Running on .NET " + Environment.Version + @"</p>

                <div class='highlight'>
                    <p>This PDF was generated without custom font resolvers or
                       System.Drawing dependencies.</p>
                </div>

                <table>
                    <tr>
                        <th>Framework</th>
                        <th>Status</th>
                    </tr>
                    <tr>
                        <td>.NET 6</td>
                        <td>Supported</td>
                    </tr>
                    <tr>
                        <td>.NET 7</td>
                        <td>Supported</td>
                    </tr>
                    <tr>
                        <td>.NET 8</td>
                        <td>Supported (LTS)</td>
                    </tr>
                    <tr>
                        <td>.NET 9</td>
                        <td>Supported</td>
                    </tr>
                    <tr>
                        <td>.NET 10</td>
                        <td>Supported</td>
                    </tr>
                </table>
            </body>
            </html>";

        using (var pdf = renderer.RenderHtmlAsPdf(htmlContent))
        {
            pdf.SaveAs("modern-dotnet-report.pdf");
        }
    }

    public async Task GeneratePdfInLinuxContainerAsync()
    {
        // Same code runs in Docker containers without libgdiplus
        // or font package installation

        var renderer = new ChromePdfRenderer();

        // Add headers and footers
        renderer.RenderingOptions.TextHeader = new TextHeaderFooter
        {
            CenterText = "Confidential Document",
            FontSize = 9
        };

        renderer.RenderingOptions.TextFooter = new TextHeaderFooter
        {
            RightText = "Page {page} of {total-pages}",
            FontSize = 9
        };

        // Render from URL - works in containers
        using (var pdf = await renderer.RenderUrlAsPdfAsync("https://example.com"))
        {
            // Merge with another PDF
            var coverPage = renderer.RenderHtmlAsPdf("<h1>Cover Page</h1>");
            var merged = PdfDocument.Merge(coverPage, pdf);

            await merged.SaveAsAsync("merged-document.pdf");
        }
    }

    public void MigrateFromPdfSharpCode()
    {
        // Example showing equivalent operations
        // PdfSharp approach required:
        // - GlobalFontSettings.FontResolver = new CustomResolver();
        // - XGraphics, XFont, XBrush for drawing
        // - Manual text positioning with DrawString()

        // IronPDF approach - HTML-based rendering
        var renderer = new ChromePdfRenderer();

        string documentHtml = @"
            <html>
            <body style='font-family: Arial, sans-serif; padding: 40px;'>
                <h1 style='color: navy;'>Invoice #12345</h1>
                <p>Date: " + DateTime.Now.ToString("yyyy-MM-dd") + @"</p>
                <hr/>
                <p>Customer: Acme Corporation</p>
                <p>Amount Due: $1,500.00</p>
            </body>
            </html>";

        using (var pdf = renderer.RenderHtmlAsPdf(documentHtml))
        {
            // Add password protection
            pdf.SecuritySettings.UserPassword = "readonly";
            pdf.SecuritySettings.OwnerPassword = "admin";
            pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;

            pdf.SaveAs("invoice.pdf");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Key points about this code:

  • Works identically on .NET 6, .NET 7, .NET 8, .NET 9, and .NET 10
  • No IFontResolver implementation required
  • No System.Drawing.Common dependency or libgdiplus installation
  • Single NuGet package for all platforms
  • Font fallback chains (Segoe UI -> Arial -> sans-serif) work automatically
  • Docker deployment requires no special font configuration

Docker Deployment

Unlike PDFsharp, IronPDF Docker deployments require no libgdiplus or font packages:

FROM mcr.microsoft.com/dotnet/aspnet:8.0

# No libgdiplus, no font packages required
# IronPDF includes everything needed

WORKDIR /app
COPY --from=build /app/publish .

ENTRYPOINT ["dotnet", "MyApp.dll"]
Enter fullscreen mode Exit fullscreen mode

API Reference

For details on modern .NET support:

Migration Considerations

Licensing

IronPDF is commercial software with perpetual licensing. A free trial is available for evaluation. Teams should compare the cost against the ongoing development time required to maintain PDFsharp font resolvers and handle version compatibility issues.

API Differences

The fundamental difference is rendering approach:

  • PDFsharp: Low-level PDF primitives (XGraphics, XFont, XBrush, manual positioning)
  • IronPDF: HTML/CSS rendering with Chromium engine

For applications already generating HTML (reports, invoices, documents), IronPDF's HTML-first approach may reduce code complexity. For applications doing programmatic drawing (charts, diagrams, custom layouts), the migration requires converting drawing code to HTML/CSS or SVG.

What You Gain

  • Consistent behavior across .NET 6, .NET 7, .NET 8, .NET 9, and .NET 10
  • No System.Drawing.Common deprecation concerns
  • No font resolver implementation or maintenance
  • Simpler Docker deployments without font packages
  • One package instead of multiple variants
  • Modern CSS support including Flexbox and Grid

What to Consider

  • Commercial licensing cost vs PDFsharp's MIT license
  • Different API paradigm (HTML vs programmatic drawing)
  • Larger deployment footprint due to embedded Chromium
  • Learning curve for teams experienced with XGraphics API

Conclusion

PDFsharp's .NET 6, .NET 7, and .NET 8 compatibility issues stem from Microsoft's System.Drawing.Common deprecation, the architectural decision to require custom font resolvers in the Core build, and the fragmentation between official and community packages. While workarounds exist, they add complexity and maintenance burden. For teams seeking straightforward PDF generation on modern .NET without managing font resolvers or System.Drawing alternatives, using a library designed natively for modern .NET eliminates the compatibility layer entirely.


Jacob Mellor, CTO at Iron Software, originally developed IronPDF and has spent over 25 years building commercial software tools.


References

  1. PDFsharp .NET Framework Support Documentation{:rel="nofollow"} - Official framework compatibility documentation
  2. PDFsharp GitHub Issue #50: Incompatible with .NET 6{:rel="nofollow"} - Original .NET 6 compatibility report
  3. PDFsharp GitHub Issue #119: .NET 6 End of Support{:rel="nofollow"} - .NET 6 support timeline discussion
  4. PDFsharp GitHub Issue #257: DLLs Loading in Multiple .NET Versions{:rel="nofollow"} - Multi-targeting assembly issues
  5. Microsoft: System.Drawing.Common Breaking Change{:rel="nofollow"} - Official deprecation documentation
  6. PDFsharp Font Resolving Documentation{:rel="nofollow"} - Font resolver requirements
  7. PDFsharp Upgrade to Version 6 Guide{:rel="nofollow"} - Migration documentation
  8. PDFsharp Choose Version Documentation{:rel="nofollow"} - Package selection guidance
  9. PdfSharpCore GitHub Repository{:rel="nofollow"} - Community fork documentation
  10. PDFsharp Forum: System.Drawing.Common Not Supported{:rel="nofollow"} - Community discussion of GDI+ exceptions

For IronPDF documentation and tutorials, visit ironpdf.com.

Top comments (0)