When creating PDFs with iTextSharp in .NET, developers frequently encounter the IOException: The document has no pages error. This exception occurs when the document.Close() method is called on a PDF that contains no content. With over 63,000 views on the original Stack Overflow question and dozens of related forum threads across the .NET community, this ranks among the most common iTextSharp errors developers face.
The Problem
The "document has no pages" error is thrown by iTextSharp when attempting to close a PDF document that contains zero pages. The exception originates in iTextSharp.text.pdf.PdfPages.WritePageTree() and indicates that the document writer has reached the finalization step without any content having been successfully added.
This error does not mean iTextSharp failed to create the document. It means the document was created, opened, and then closed without any renderable content ever being added between those operations. The library considers an empty PDF invalid and throws an exception rather than producing a zero-byte or malformed file.
The confusing aspect for many developers is that they believe they added content. The error message provides no indication of why the content was not present, only that the final document contained nothing to write.
Error Messages and Symptoms
The primary exception takes this form:
iTextSharp.text.exceptions.IOException: The document has no pages.
at iTextSharp.text.pdf.PdfPages.WritePageTree()
at iTextSharp.text.pdf.PdfWriter.Close()
at iTextSharp.text.Document.Close()
Related errors that often accompany or precede this issue include:
System.IO.IOException: The document has no pages.
The document is not open yet; you can only add Meta information.
The document has been closed. You can't add any Elements.
These secondary errors provide more specific information about what went wrong, but they may be caught and suppressed before the "no pages" error surfaces.
Who Is Affected
This error affects any .NET application using iTextSharp (the .NET port of iText) for programmatic PDF generation. The following scenarios are particularly prone to this issue:
Frameworks: All .NET versions where iTextSharp is supported, including .NET Framework 4.x, .NET Core, and .NET 5+.
Use Cases:
- Report generation systems that may produce empty result sets
- Export functionality for GridViews or DataTables
- Document assembly where content is conditionally included
- Template-based PDF generation where variables may be empty
- ColumnText layouts where content exceeds available space
Development Stage: This error predominantly appears during development and testing, as it typically indicates a logic error rather than a runtime environment issue. However, production systems that do not validate data before PDF generation can encounter this when users request exports of empty data sets.
Evidence from the Developer Community
The "document has no pages" error has generated extensive discussion across developer forums, with the original Stack Overflow question accumulating over 63,000 views since 2013.
Timeline
| Date | Event | Source |
|---|---|---|
| 2008 | Early reports on iText mailing lists | iText Mailing Archives |
| 2013-10-09 | Primary Stack Overflow question posted | Stack Overflow |
| 2014-2018 | Multiple related questions across ASP.NET Forums, CodeProject | Various |
| 2015-present | Recurring issues with PDF reporting libraries | GitHub Issues |
| 2021-05-19 | Continued activity on original question | Stack Overflow |
Community Reports
The problem manifests in several distinct patterns. One common scenario involves GridView exports:
"This error means your GridView is empty and hence there is nothing to export."
-- ASP.NET Snippets Forums
Developers using ColumnText for precise text positioning encounter a related variant:
"You may be trying to add the text into a rectangle which is too small. As a result, nothing is added to the PDF and rather than showing an empty page, iText throws an exception."
-- iText Knowledge Base
The mailing list archives reveal frustrated developers who believed they had added content:
"document has no pages (grrr) - I've added paragraphs and tables but still get this error"
-- iTextSharp Mailing List
A particularly instructive case involved a developer adding tables to documents:
"I had this same error despite adding a table to the document, then adding cells and content. I needed to add the cells and content before adding the table to the document."
-- Experts Exchange
Root Cause Analysis
The error stems from iTextSharp's document lifecycle and the disconnect between calling methods and actually rendering content. Understanding the five-step PDF creation process explains why content can appear to be added yet not exist in the final document.
The Five Steps of iTextSharp PDF Creation
-
Create a Document object:
Document document = new Document(); -
Get a PdfWriter instance:
PdfWriter.GetInstance(document, outputStream); -
Open the document:
document.Open(); -
Add content:
document.Add(paragraph); -
Close the document:
document.Close();
The "no pages" error occurs at step 5 when step 4 either did not execute or did not successfully add renderable content.
Why Content May Not Be Added
Exception Between Open and Close: If an exception occurs during content addition but is caught and suppressed, execution continues to document.Close() without any content. Missing fonts, invalid images, and permission errors can all cause silent failures.
// Problematic pattern - exception swallowing
try
{
document.Open();
try
{
document.Add(new Paragraph("Content", problematicFont)); // May throw
}
catch { } // Silent failure
}
finally
{
document.Close(); // Throws "no pages" because Add failed
}
Adding Containers Before Content: iTextSharp measures element size at add time, not render time. Adding an empty table or container results in a zero-size element that does not create a page.
// Incorrect order - table is empty when added
var table = new PdfPTable(3);
document.Add(table); // Added with zero rows - no page created
table.AddCell("Data"); // Too late, table already added
ColumnText Rectangle Too Small: When using ColumnText for positioned text, if the specified rectangle cannot contain any content, nothing is added.
// Rectangle too small to contain text
column.SetSimpleColumn(new Phrase("Long text content"), 10, 10, 20, 20, 18, Element.ALIGN_CENTER);
column.Go();
document.Close(); // No pages - text did not fit
Conditional Logic Not Executing: Data-driven PDF generation may skip all content addition when the data source is empty.
// No content added when dataSource is empty
foreach (var item in dataSource) // Empty collection
{
document.Add(new Paragraph(item.ToString())); // Never executes
}
Attempted Workarounds
Developers have employed several approaches to avoid or diagnose this error.
Workaround 1: Validate Data Before Generation
Approach: Check that data exists before attempting PDF generation.
public void ExportToPdf(IEnumerable<ReportRow> data)
{
if (!data.Any())
{
throw new InvalidOperationException("No data to export");
}
// Proceed with PDF generation
}
Limitations: This only addresses the empty data scenario. It does not catch silent failures during content addition caused by font issues, image loading failures, or other exceptions.
Workaround 2: Add a Placeholder Page
Approach: Always add at least one element to ensure a page exists.
document.Open();
// Add actual content
foreach (var item in data)
{
document.Add(new Paragraph(item.ToString()));
}
// Ensure at least one page exists
if (!document.IsOpen() || document.PageNumber == 0)
{
document.Add(new Paragraph("No data available."));
}
document.Close();
Limitations: This masks the root cause rather than addressing it. The resulting PDF contains placeholder content that may confuse users. The PageNumber check is not always reliable depending on when elements trigger new pages.
Workaround 3: Proper Exception Handling
Approach: Never suppress exceptions during the content addition phase.
Document document = null;
try
{
document = new Document();
PdfWriter.GetInstance(document, outputStream);
document.Open();
// Let exceptions propagate
document.Add(new Paragraph("Content", font));
document.Add(table);
}
catch (DocumentException ex)
{
// Log and rethrow - do not suppress
throw;
}
finally
{
if (document != null && document.IsOpen())
{
try { document.Close(); }
catch (IOException) { } // Okay to suppress here - document already failed
}
}
Limitations: This improves diagnostics but does not prevent the underlying issues. Developers still need to validate fonts, images, and other resources before use.
Workaround 4: Correct Element Addition Order
Approach: Populate containers before adding them to the document.
// Correct order - populate table first
var table = new PdfPTable(3);
table.AddCell("Column 1");
table.AddCell("Column 2");
table.AddCell("Column 3");
foreach (var row in data)
{
table.AddCell(row.Field1);
table.AddCell(row.Field2);
table.AddCell(row.Field3);
}
document.Add(table); // Table has content when added
Limitations: Requires understanding iTextSharp's internal behavior. The documentation does not prominently warn that element size is calculated at add time.
A Different Approach: IronPDF
IronPDF takes a fundamentally different approach to PDF generation that eliminates several categories of errors, including the "document has no pages" scenario.
Rather than requiring developers to manage a document lifecycle with separate open, add, and close operations, IronPDF uses an HTML-to-PDF rendering model. Content is provided as HTML, and the rendering engine produces a complete PDF in a single operation. There is no intermediate state where a document can exist without content.
Why IronPDF Avoids This Issue
IronPDF uses an embedded Chromium rendering engine. When you call RenderHtmlAsPdf(), the entire operation is atomic:
- HTML content is passed to the renderer
- Chromium renders the HTML to a PDF
- The PDF is returned as a complete document
There is no "document" object to open and close, no content addition phase that can silently fail, and no lifecycle management that depends on correct ordering of operations.
If the HTML is empty or whitespace-only, IronPDF produces a single blank page rather than throwing an exception. If resources fail to load (missing images, inaccessible CSS), the page renders with the failures visible rather than causing a cryptic error.
Code Example
The following example demonstrates generating a PDF report that may have variable data:
using IronPdf;
using System.Collections.Generic;
using System.Text;
public class ReportGenerator
{
public byte[] GenerateReport(IEnumerable<ReportItem> items)
{
// Build HTML content
var html = new StringBuilder();
html.Append(@"
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4472C4; color: white; }
tr:nth-child(even) { background-color: #f9f9f9; }
.empty-message { color: #666; font-style: italic; }
</style>
</head>
<body>
<h1>Report</h1>");
var itemList = items.ToList();
if (itemList.Count == 0)
{
// Renders a valid PDF with a message - no exception
html.Append("<p class='empty-message'>No data available for this report.</p>");
}
else
{
html.Append(@"
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Value</th>
</tr>");
foreach (var item in itemList)
{
html.AppendFormat(@"
<tr>
<td>{0}</td>
<td>{1}</td>
<td>{2:C}</td>
</tr>",
item.Id,
System.Web.HttpUtility.HtmlEncode(item.Name),
item.Value);
}
html.Append("</table>");
}
html.Append("</body></html>");
// Single atomic operation - no open/close lifecycle
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html.ToString());
return pdf.BinaryData;
}
}
public class ReportItem
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Value { get; set; }
}
Key points about this code:
- No
Document.Open()orDocument.Close()calls to manage - Empty data produces a valid PDF with a message, not an exception
- HTML content is validated by the browser engine, providing clear error messages for malformed markup
- Font availability is handled by Chromium with automatic fallbacks
Comparison: iTextSharp vs IronPDF Approach
Consider a scenario where a GridView export might have no data:
iTextSharp Pattern (Exception-Prone):
Document document = new Document();
PdfWriter.GetInstance(document, Response.OutputStream);
document.Open();
// If gridView.Rows is empty, nothing is added
foreach (GridViewRow row in gridView.Rows)
{
// Add content
}
document.Close(); // Throws if no rows existed
IronPDF Pattern (Always Produces Valid Output):
var renderer = new ChromePdfRenderer();
// Build HTML representation of GridView
string html = ConvertGridViewToHtml(gridView);
// Always produces a valid PDF
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("export.pdf");
API Reference
For more details on the methods used:
- ChromePdfRenderer - Main rendering class for HTML-to-PDF conversion
- RenderHtmlAsPdf - Converting HTML strings to PDF documents
- PDF Generation Examples - Additional code samples
Migration Considerations
When evaluating a switch from iTextSharp to IronPDF, consider the following factors.
Licensing
iTextSharp uses AGPL licensing, which requires source code disclosure for applications that distribute iTextSharp-generated PDFs. Commercial iText licenses are available but require separate negotiation. IronPDF uses commercial licensing with transparent pricing and a free trial for evaluation.
API Differences
The fundamental API paradigm differs between the libraries:
| iTextSharp | IronPDF |
|---|---|
| Document lifecycle (open/add/close) | Single render operation |
| Element-based construction | HTML/CSS-based layout |
| Manual font embedding | Automatic font handling via Chromium |
| PdfPTable, PdfPCell objects | HTML <table> elements |
| Coordinate-based positioning | CSS positioning |
For applications heavily invested in iTextSharp's element API with precise positioning requirements, migration requires rethinking content as HTML/CSS. For applications already generating HTML or using templating engines, migration is typically straightforward.
What You Gain
- Elimination of document lifecycle errors
- Full CSS3 support for styling and layout
- JavaScript execution for dynamic content
- Predictable error messages for missing resources
- Simplified API with fewer edge cases
What to Consider
- IronPDF requires a commercial license for production use
- Chromium-based rendering adds approximately 50MB to deployment size
- Rendering performance characteristics differ from iTextSharp for certain document types
- Some low-level PDF manipulation features available in iText are not present in IronPDF
Conclusion
The iTextSharp "document has no pages" error occurs when the document lifecycle completes without renderable content. The root causes range from empty data sources to silent exceptions during content addition to incorrect element ordering. While workarounds exist, they require understanding iTextSharp's internal behavior and careful exception handling throughout the PDF generation process.
IronPDF's HTML-to-PDF approach eliminates this category of error by design. The single atomic render operation has no intermediate state where a document can exist without content, and empty input produces a valid blank page rather than an exception.
Written by Jacob Mellor, CTO at Iron Software and original developer of IronPDF.
References
- iTextSharp "The document has no pages." - Stack Overflow{:rel="nofollow"} - Original question with 63,000+ views
- Why does using ColumnText result in "The document has no pages" exception? - iText KB{:rel="nofollow"} - Official iText documentation of the ColumnText variant
- The document has no pages error - iText Mailing List{:rel="nofollow"} - Community discussion of root causes
- itext export to pdf - Document has no page - ASP.NET Forums{:rel="nofollow"} - GridView export scenario
- The document has no pages itextsharp error - C# Corner{:rel="nofollow"} - Discussion of table ordering issues
- Error The document has no pages - CodeProject{:rel="nofollow"} - Font-related variant
- IOException: The document has no pages - PdfReport.Core GitHub{:rel="nofollow"} - Reporting library issue
- itextsharp error: "the document has no pages" problem - Experts Exchange{:rel="nofollow"} - Element ordering solution
For the latest IronPDF documentation and tutorials, visit ironpdf.com.
Top comments (0)