Below are solutions to the most frequently encountered issues when using CobaltPDF. If your problem isn't listed here, check the documentation or contact us at support@cobaltpdf.com.

Chromium requires several system libraries that are not installed by default in minimal Linux images or Docker containers.

Solution: Use the built-in cloud environment preset to configure the engine for your platform:

CobaltEngine.Configure(CloudEnvironment.ConfigureForDocker);

If you're building a custom Docker image, ensure these packages are installed:

RUN apt-get update && apt-get install -y \
    libnss3 libatk1.0-0 libatk-bridge2.0-0 \
    libcups2 libdrm2 libxkbcommon0 libxcomposite1 \
    libxdamage1 libxrandr2 libgbm1 libpango-1.0-0 \
    libcairo2 libasound2 libxshmfence1 fonts-liberation

For Azure App Service, use CloudEnvironment.ConfigureForAzure instead.

A blank or incomplete PDF usually means the page hadn't finished rendering when CobaltPDF captured it. This is common with JavaScript-heavy pages (React, Vue, Angular).

Solution: Use a wait strategy to delay capture until the page is ready:

// Wait for the network to be idle
var pdf = await renderer
    .WithWaitStrategy(WaitOptions.DefaultNetworkIdle)
    .RenderUrlAsPdfAsync(url);

// Or wait for a specific DOM element
var pdf = await renderer
    .WithWaitStrategy(WaitOptions.ForSelector("#main-content"))
    .RenderUrlAsPdfAsync(url);

For SPAs, call window.cobaltNotifyRender() from your front-end code when the app is fully loaded, and use .WithWaitStrategy(WaitOptions.ForSignal()) on the engine.

Fonts appear as fallbacks (e.g. Times New Roman) when the required font files are not available on the server.

Solutions:

  • Web fonts: Use Google Fonts or other CDN-hosted fonts in your HTML. These are downloaded by Chromium at render time.
  • Local fonts: Install the font files on the server, or use .WithFonts("path/to/fonts") to register them before rendering.
  • Docker: Include font files in your Docker image and install them with fc-cache -f -v.

If you're using custom web fonts, ensure .WithWaitStrategy(WaitOptions.DefaultNetworkIdle) is enabled so Chromium finishes downloading them before capture.

Chromium processes can accumulate memory over many renders. CobaltPDF mitigates this by recycling browser instances after a configurable number of renders.

Solution: Reduce the recycle threshold and cap the pool size:

builder.Services.AddCobaltPdf(options =>
{
    options.PoolSize = 2;             // fewer concurrent browsers
    options.RecycleAfter = 25;        // recycle after 25 renders
    options.CloudEnvironment =
        CloudEnvironment.ConfigureForLowMemory;
});

The ConfigureForLowMemory preset disables GPU compositing and reduces shared memory requirements.

The default render timeout is 30 seconds. Large pages with many images, complex layouts, or slow external resources may exceed this.

Solution: Increase the timeout for specific renders:

var pdf = await renderer
    .WithTimeout(TimeSpan.FromSeconds(60))
    .RenderUrlAsPdfAsync(url);

If the page loads many external resources, consider using .WithWaitStrategy(WaitOptions.DefaultNetworkIdle) instead of a fixed delay, as it adapts to the actual load time.

Tip: Pass a CancellationToken to allow callers to cancel long-running renders gracefully.

Headers and footers require sufficient page margins to be visible. If margins are too small, Chromium clips the header/footer content.

Solution: Set explicit top and bottom margins that are large enough to contain your header/footer HTML:

var pdf = await renderer
    .WithHeader(headerHtml)
    .WithFooter(footerHtml)
    .WithMargins(top: "30mm", bottom: "25mm")
    .RenderUrlAsPdfAsync(url);

Header/footer templates are rendered in an isolated context with a fixed height. Use inline styles only — external stylesheets are not loaded in the header/footer context.

By default, Chromium does not print background colours and images when generating a PDF. This is the same behaviour as the browser's print dialog.

Solution: Enable background printing:

var pdf = await renderer
    .WithPrintBackground()
    .RenderUrlAsPdfAsync(url);

If specific elements are hidden in print, check for @media print rules in your CSS that may be hiding them. You can also use .WithMediaType(CssMediaType.Screen) to force screen styles instead of print styles.

This can occur when PreWarmAsync() is called before the engine has fully initialised, or when the engine is disposed during pre-warming (e.g. during application shutdown).

Solution: Ensure Configure() completes before calling PreWarmAsync(). In ASP.NET Core, call it after Build():

var app = builder.Build();

// Configure first, then pre-warm
CobaltEngine.Configure(CloudEnvironment.ConfigureForDocker);
await app.Services
    .GetRequiredService<CobaltEngine>()
    .PreWarmAsync();

app.Run();

If the error occurs during shutdown, it can safely be caught and ignored — the browser processes are cleaned up regardless.