Release history for CobaltPDF, CobaltPDF.WebKit & CobaltPDF.Requests
v1.6.2
Fixed
Azure preset no longer breaks multi-page PDFs.CloudEnvironment.ConfigureForAzure (and ConfigureForLowMemory) no longer add --single-process — that flag crashes the Chromium renderer on multi-page or non-trivial documents (only trivial single-page renders survived it). 1.6.1 could fail real renders on Azure when these presets were used, so upgrading from 1.6.1 is recommended. The presets now use the stable multi-process model.
Changed
The bundled Linux dependencies (added in 1.6.1) now activate only when the host is missing Chromium's graphics stack, so Linux hosts that already provide the libraries render exactly as before.
v1.6.1
Added
Runs on stock Linux with no container. The package now ships Chromium's OS-level dependencies (system libraries, NSS modules, and base fonts) and points the browser's loader at them automatically on Linux — so the Chromium edition runs on a stock Azure Functions Linux plan or a slim container with a plain code deploy (no custom container, no apt). On Linux hosts that already provide the libraries, nothing changes: the host's own libraries and fonts are used exactly as before, and the bundled set is used only when the host is missing them.
CobaltPDF.Requests dependency pinned to v1.6.1.
v1.6.0
Added
WithCompression(bool) — output PDFs now re-encode embedded images to shrink the file (typically several times smaller on image-heavy pages). Call WithCompression(false) for raw, lossless output. Powered by Magick.NET (Apache-2.0).
WithViewportSize(width[, height]) — sets the render viewport; a tall height triggers IntersectionObserver lazy images without scrolling. Parity with the WebKit edition.
WithEagerImages() — forces lazy-loaded images to load before rendering, additionally promoting the JavaScript data-src/data-srcset convention the print path cannot.
Pool backpressure & metrics. New PoolOptions.MaxQueueDepth + PoolBusyException let a saturated pool fast-fail extra requests so the host can return HTTP 503 instead of a slow timeout (default 0 = unbounded). New CobaltEngine.GetPoolStatistics() / CobaltPoolStatistics expose live pool gauges and lifetime counters for health endpoints.
Changed
Desktop-layout rendering by default. Renders now capture the full desktop layout (≈1280 px wide) scaled to fit the page — matching the WebKit edition — instead of reflowing to the narrow print width. The paper keeps its true size (e.g. A4). Set WithMediaType(CssMediaType.Print) to restore the old Chrome-print reflow.
Image compression is on by default (see above), so output is now slightly lossy unless you call WithCompression(false).
Default User-Agent now matches the WebKit edition (a desktop Chrome UA via PdfOptions.DefaultUserAgent) so UA-sensitive sites serve both engines the same markup. Override with WithUserAgent(...).
Auto-sized concurrency.PoolOptions.MaxSize now defaults to a host-aware value — the smaller of the vCPU count and what fits in ~75% of detected memory, clamped 1–8 — instead of a fixed 5, so it stays safe on memory-constrained hosts. Always overridable.
CobaltPDF.Requests dependency updated to v1.6.1.
Deprecated
WithoutPostProcessing() — use WithCompression(bool) instead (WithoutPostProcessing() is equivalent to WithCompression(false)). It still compiles, and is no longer a no-op on this edition.
Compatibility
No public API was removed; existing code compiles and runs unchanged. The default output now differs (desktop-scaled layout + image compression) — combine WithMediaType(CssMediaType.Print) and WithCompression(false) to reproduce v1.5.x output.
v1.5.0
Added
PDF page splitting, extraction & merging. New PdfDocument members: PageCount, ExtractPage(int), ExtractPages(start, end), ExtractPages(IEnumerable<int>), SplitIntoPages(), and static FromFile(path), FromBytes(data), and Merge(params PdfDocument[]). Works on any PDF — freshly rendered or loaded from disk — on any OS. Page indices are 0-based; out-of-range indices throw ArgumentOutOfRangeException.
Watermark rasterization. New opt-in WatermarkOptions.Rasterize flag (fluent .WithRasterize()) flattens a watermark into a high-resolution image baked into every page — no selectable text and no separate deletable object in a PDF editor. Tamper-resistance for confidential documents; default behaviour is unchanged. The same flag was added to CobaltPDF.WebKit, so both libraries behave identically.
WithoutPostProcessing() added as an accepted no-op for drop-in compatibility with CobaltPDF.WebKit (where it skips a separate post-processing pipeline). Chromium's PDF backend already subsets fonts and compresses images natively, so the method has no effect here — code written against either engine compiles and runs against the other unchanged.
Security
Encryption upgraded to AES-256 (security handler V5/R6, previously AES-128). The WithEncryption(...) API, PdfEncryptionOptions, and all password/permission behaviour are unchanged — only the cipher strength improved. Both CobaltPDF libraries now produce identical AES-256 protection from identical options.
Changed
CobaltPDF.Requests dependency updated to v1.5.0 — a serialized PdfRequest can now request a rasterized watermark and carry the new SkipPostProcessing flag (honoured by CobaltPDF.WebKit; accepted and ignored here).
Deployment documentation corrected and expanded after validation on real Azure infrastructure: Linux Azure Functions require a custom container for Chromium (the stock image lacks its system libraries) — the Azure Functions guide and docs now carry validated container walkthroughs and engine toggles.
Compatibility
Fully backward compatible — no public API was renamed or removed, and existing code compiles and runs unchanged.
v1.4.1
Added
WithUserAgent, WithHttpHeader, and WithHttpHeaders are now declared on the IPdfGenerator and IPdfGeneratorFinal interfaces (previously only available on CobaltEngine), so code holding an interface reference gets the same methods via IntelliSense.
Fixed
AddCookie(name, value) without an explicit domain no longer throws "Invalid cookie fields" when the final URL is localhost, an IPv4/IPv6 address, or a single-label intranet hostname. The cookie is now correctly registered as a standard host-only cookie. Cookie inference for public domains is unchanged.
v1.4.0
Security
Updated bundled Chromium from 2026.2.1 to 2026.5.16, addressing upstream security advisories.
Removed
Dropped the net6.0 target. The package now targets net8.0 (compatible with .NET 8, 9, and 10). Consumers on .NET 6 should stay on v1.3.0 or upgrade their runtime — .NET 6 reached end of Microsoft support in November 2024.
Changed
Bumped Microsoft.Extensions.DependencyInjection from 10.0.3 to 10.0.8.
Bumped System.Formats.Asn1 from 10.0.3 to 10.0.8.
Bumped Microsoft.Playwright from 1.58.0 to 1.60.0.
v1.3.0
Added
Multi-target support: the package now ships builds for both net6.0 and net8.0, broadening compatibility with projects on .NET 6, 7, 8, 9, and 10.
Changed
CobaltPDF.Requests dependency updated to v1.3.0 (now targets netstandard2.0).
v1.2.2
Fixed
Fixed Chromium default header/footer appearing when only one template is provided.
Fixed WithLazyLoadPages not working when combined with WithCustomJS or WithWaitStrategy.
Changed
WithCustomJS now waits for the page to be fully loaded before executing, so dynamically-injected elements (e.g. cookie consent buttons) are available.
Client-side redirects (e.g. bbc.com → bbc.co.uk) are now detected before cookies, custom JS, and wait strategies run.
v1.2.0
Changed
Renamed .Landscape() to .WithLandscape() for fluent API consistency.
Renamed .UseGrayscale() to .WithGrayscale() for fluent API consistency.
Renamed .EmulateMediaType() to .WithMediaType() — shorter and consistent with the With* convention.
Renamed .WaitFor() to .WithWaitStrategy() to avoid confusion with async operations.
Renamed .ReloadAfterStorageSet() to .WithReloadAfterStorage() for fluent API consistency.
Renamed .ConfigureFonts() to .WithFonts() — shorter and consistent with the With* convention.
v1.1.0
Added
Fluent .WithWatermark() API for text and HTML watermarks with configurable opacity, rotation, and position.
PDF metadata support — set title, author, subject, keywords, and creator via .WithMetadata().
CloudEnvironment.ConfigureForAzure preset for Azure App Service and Container Apps deployments.
New .ScrollPage() option to trigger lazy-loaded images before capture.
Changed
Default pool MaxSize increased from 4 to 8 for better throughput on multi-core hosts.
Improved browser recycling logic — instances are now recycled after 50 renders (previously 100).
Fixed
Resolved rare deadlock when calling RenderUrlAsPdfAsync with a CancellationToken that fires during navigation.
Fixed header/footer templates not respecting @media print styles.
v1.0.1
Fixed
Fixed PreWarmAsync() throwing ObjectDisposedException when called immediately after Configure() on Linux containers.
Corrected paper size calculation for custom dimensions specified in millimetres.
Resolved an issue where AddCookie() cookies were not sent on the initial page load when using RenderUrlAsPdfAsync.
v1.0.0
Added
Initial release of CobaltPDF — a high-performance HTML-to-PDF rendering engine for .NET.
Chromium-powered rendering with full support for modern CSS (Grid, Flexbox, custom properties, animations).
Managed browser pool with configurable MinSize, MaxSize, and automatic recycling.
Fluent API for PDF generation — chain options and call a single terminal method.
Thread-safe singleton design with isolated browser contexts per render.
Cookie, localStorage, and sessionStorage injection per render.
Custom HTTP headers and User-Agent per render.
Header and footer HTML templates with page number, total pages, and date tokens.
PDF encryption with user/owner passwords and granular permission control.
ASP.NET Core dependency injection via services.AddCobaltPdf().
Companion package CobaltPDF.Requests for lightweight microservice clients.
v1.6.2
Fixed
Memory leak on Linux fixed. Recycled render workers no longer leave a process behind, so steady memory stays flat over long-running services. Render output unchanged; upgrading from 1.6.0 / 1.6.1 is recommended.
v1.6.1
Fixed
Docker reliability & diagnostics. In a container that lacks the host's webkit2gtk runtime, the render bundle falls back to proot, whose ptrace path-remapping can hang under Docker's default seccomp. The engine now logs the cause and the fix up front instead of failing silently. Recommended Docker recipe: an Ubuntu 24.04 base with apt-get install -y libwebkit2gtk-4.1-0 xvfb (see the Docker guide). No change to managed Linux hosts (Azure App Service / Functions / Container Apps), where the self-provisioning bundle runs as before.
Changed
CobaltPDF.Requests dependency pinned to v1.6.1.
v1.6.0
Added
Pool backpressure. New PoolOptions.MaxQueueDepth + PoolBusyException: when the pool is saturated and the wait-queue is full, renders fast-fail so a host can return HTTP 503 + Retry-After instead of a slow, opaque timeout. Default 0 = unbounded (unchanged behaviour).
Host-aware memory cap.PoolOptions.MaxMemoryMb is auto-clamped to ~80% of detected host memory, so the soft cap fires with a clean error before the kernel OOM-kills the process on a small plan.
Pool metrics. New CobaltEngine.GetPoolStatistics() / CobaltPoolStatistics expose live gauges (workers, leased, idle, queued) and lifetime counters for health and metrics endpoints.
WithEagerImages() — forces lazy-loaded images to load before rendering (flips loading="lazy" to eager and promotes data-src/data-srcset); a fast, non-scrolling alternative to WithLazyLoadPages.
Viewport via PdfRequest — WithViewportSize(width[, height]) is now settable through the request model as well as fluently.
Changed
Auto-sized concurrency.PoolOptions.MaxSize now defaults to a host-aware value — the smaller of the vCPU count and how many workers fit in ~75% of detected memory (~450 MB each), clamped 1–8 — instead of a fixed 5, so it stays safe on memory-constrained hosts instead of OOMing. Always overridable.
Transient single-render retry-on-worker-crash hardened, and surfaced via the new metrics counters.
CobaltPDF.Requests dependency updated to v1.6.1.
Deprecated
WithoutPostProcessing() — use WithCompression(bool) instead (WithoutPostProcessing() is equivalent to WithCompression(false): raw, uncompressed output). The old name still works.
Compatibility
Render output is byte-for-byte unchanged — every change is additive or operational. Verified against the v1.5.0 output baseline.
v1.5.0
Added
Initial public release of CobaltPDF.WebKit — a headless WebKit-based HTML-to-PDF library for .NET 8+, drop-in API-compatible with CobaltPDF (Chromium): the same CobaltEngine type, the same fluent methods, the same options. Activated by the same CobaltPDF license key.
Lighter idle footprint. Lower idle memory than Chromium — roughly 40% less (~130 MB vs ~240 MB idle heap, both engines measured identically on the same Linux host) — and the engine releases memory back to the host between renders. The trade-off is render speed: Chromium is faster. Per-render memory metrics exposed via PdfDocument.PeakRssBytes and SteadyRssBytes.
Self-provisioning Linux engine. On Linux x64 (glibc ≥ 2.35 — Ubuntu 22.04+/24.04, Debian 12+) the library downloads, verifies (SHA-256), and extracts a fully self-contained WebKit bundle on first use — no Docker, no apt, no system setup. Validated end-to-end on stock Azure Functions and App Service Linux plans. Air-gapped deployments can ship the bundle inside the publish output, pre-stage the tarball, or point at a private feed.
WithoutPostProcessing() raw-output mode — skip the post-processing pipeline (font subsetting, image re-encoding) for ~30 MB lower peak memory and faster renders, at the cost of larger files. Ideal for transient PDFs on memory-constrained hosts.
Cold-start hardening. Freshly provisioned instances prime the engine's font caches on a throwaway render before serving traffic, interrupted downloads resume from a hash-verified cached tarball, and renders retry once on a fresh worker after transient failures.
Windows & macOS development backends. Renders through WSL2 (recommended on Windows) or Docker Desktop automatically; an opt-in stub mode produces placeholder PDFs for offline development.
Full feature parity with the Chromium edition: warm renderer pool, headers & footers, cookies and storage injection, HTTP headers and User-Agent, wait strategies, custom JavaScript, custom fonts, lazy loading, metadata, watermarks (including rasterized watermarks via .WithRasterize()), and AES-256 encryption with user/owner passwords and permission flags.
PDF page splitting, extraction & merging via PdfDocument — PageCount, ExtractPage, ExtractPages, SplitIntoPages(), FromFile, FromBytes, and Merge — identical to the Chromium edition.
CobaltPDF.Requests v1.5.0 support — the same serialized PdfRequest executes against either a Chromium or WebKit rendering service via PdfRequest.ExecuteAsync, including the new SkipPostProcessing flag.
v1.6.1
Added
PdfRequest.Compress (and PdfRequestBuilder.WithCompression(bool)) — controls output PDF compression; defaults to true. Maps to WithCompression(bool) in both the CobaltPDF (Chromium) and CobaltPDF.WebKit 1.6.0+ editions.
PdfRequest.ViewportWidth / ViewportHeight (and PdfRequestBuilder.WithViewportSize(width[, height])) — sets the render viewport; a tall height triggers IntersectionObserver lazy images without scrolling.
PdfRequest.ForceEagerImages (and PdfRequestBuilder.WithEagerImages()) — forces lazy-loaded images to load before rendering. Honoured by both editions.
Deprecated
PdfRequestBuilder.WithSkipPostProcessing() — use WithCompression(false) instead. The legacy SkipPostProcessing property is retained as the inverse of Compress for backward compatibility.
Compatibility
Purely additive — existing PdfRequest JSON (including the older SkipPostProcessing flag) deserializes and behaves exactly as before.
v1.6.0
Added
Fluent builder for PdfRequest — mirrors the CobaltEngine fluent API, so authoring a request reads the same as rendering one. Start with PdfRequest.ForUrl(url) or PdfRequest.ForHtml(html), chain .WithPaperFormat(), .WithMargins(), .WithHeader(), .WithWatermark(), .WithEncryption(), .WithMetadata(), .AddCookie() and more, then call .Build(). PdfRequest.ToBuilder() adapts an existing instance.
Compatibility
Purely additive — PdfRequest is unchanged and object-initializer construction works exactly as before. The fluent path produces an identical PdfRequest (and identical JSON on the wire).
v1.5.0
Added
PdfRequest.SkipPostProcessing (bool, default false) — ask the rendering service to skip its PDF post-processing pipeline and return raw engine output: lower memory and latency, larger files; watermark, encryption, and metadata are ignored when set. Honoured by CobaltPDF.WebKit; the Chromium edition accepts and ignores it (its PDF backend already optimises natively).
Compatibility
One new optional JSON property ("skipPostProcessing"). Older clients that don't send it get the existing behaviour; older servers ignore the unknown property — mixed-version client/server combinations keep working.
v1.4.0
Added
PdfRequestWatermark.Rasterize (bool, default false) — ask the rendering service to flatten a watermark into a non-editable image baked into every page, matching the new WatermarkOptions.Rasterize capability in both CobaltPDF and CobaltPDF.WebKit.
Compatibility
One new optional JSON property ("rasterize") on the watermark object. Older clients that don't send it get the existing vector behaviour; older servers ignore the unknown property — mixed-version client/server combinations keep working.
v1.3.0
Changed
Retargeted from net8.0 to netstandard2.0 for maximum compatibility — usable from .NET Framework 4.6.1+, .NET Core 2.0+, and all modern .NET versions.
v1.2.0
Added
Added PdfRequestMargins, PdfRequestWatermark, PdfRequestEncryption, and PdfRequestMetadata models.
Added PdfResponse with FromBytes() and ToStream() helpers.
v1.0.0
Added
Initial release — lightweight PdfRequest and PdfResponse models for sending PDF generation requests to a CobaltPDF-powered microservice.
Full JSON-serialisable request model mirroring the CobaltPDF fluent API.
Cookie, header, encryption, metadata, watermark, and wait strategy support.