How to Handle Errors and Debug Barcode Operations in C#

Barcode processing pipelines can fail silently, with zero results often mistaken for 'no barcode present.' However, issues like corrupted files, password-protected PDFs, or format mismatches may be responsible. Implementing proper logging and structured error handling uncovers these failures and provides actionable diagnostics.

IronBarcode offers a typed exception hierarchy in the IronBarCode.Exceptions namespace, a built-in logging API, and detailed BarcodeResult properties. These properties include the detected format, decoded value, page number, and coordinates for each successful decode.

This how to explains how to catch and interpret typed exceptions, extract diagnostic context from failed reads, enable structured logging, and isolate failures during batch operations.

Quickstart: Handle Barcode Errors and Enable Diagnostics

Wrap read/write calls in try-catch blocks targeting IronBarcode's typed exceptions to surface actionable error messages instead of silent failures.

  1. Install IronBarcode with NuGet Package Manager

    PM > Install-Package BarCode
  2. Copy and run this code snippet.

    using IronBarCode;
    using IronBarCode.Exceptions;
    
    try
    {
        BarcodeResults results = BarcodeReader.Read("label.pdf");
        Console.WriteLine($"Found {results.Count} barcode(s)");
    }
    catch (IronBarCodeFileException ex)
    {
        Console.Error.WriteLine($"File error: {ex.Message}");
    }
  3. Deploy to test on your live environment

    Start using IronBarcode in your project today with a free trial

    arrow pointer

How Do I Catch and Interpret IronBarcode Exceptions?

Catch IronBarcode exceptions from the most specific to the most general. Order catch blocks to handle actionable exceptions first, such as file, PDF password, and encoding errors, followed by the base type. The IronBarCode.Exceptions namespace defines 11 exception types, each corresponding to a specific failure mode:

IronBarcode Exception Types — Causes and Recommended Fixes
Exception TypeTriggerRecommended Fix
IronBarCodeFileExceptionFile is corrupted, locked, or in an unsupported image formatValidate the file is a supported image format and is not locked; also catch FileNotFoundException separately for missing files
IronBarCodePdfPasswordExceptionPDF is password-protected or encryptedSupply password via PdfBarcodeReaderOptions, or skip file and log
IronBarCodeEncodingExceptionGeneric encoding failure during barcode generationVerify input data matches the target BarcodeWriterEncoding constraints
IronBarCodeContentTooLongEncodingExceptionValue exceeds the character limit for the selected symbologyTruncate data or switch to a higher-capacity format (QR, DataMatrix)
IronBarCodeFormatOnlyAcceptsNumericValuesEncodingExceptionNon-numeric characters passed to a numeric-only format (EAN, UPC)Sanitize input or switch to an alphanumeric format (Code128, Code39)
IronBarCodeUnsupportedRendererEncodingExceptionSelected BarcodeEncoding is not writable by IronBarcodeUse BarcodeWriterEncoding enum instead of BarcodeEncoding
IronBarCodeParsingExceptionStructured data (GS1-128) fails validation during parsingValidate GS1 structure with Code128GS1Parser.IsValid() before parsing
IronBarCodeNativeExceptionError in native interop layer (missing DLLs, platform incompatibility)Verify platform-specific NuGet packages are installed (BarCode.Linux, BarCode.macOS)
IronBarCodeConfidenceThresholdExceptionInvalid confidence threshold argument passed to reader optionsEnsure ConfidenceThreshold is between 0.0 and 1.0
IronBarCodeUnsupportedExceptionOperation not supported in the current contextCheck the changelog for feature availability in your version
IronBarCodeExceptionBase type — catches any IronBarcode-specific error not matched aboveLog full exception details and escalate for investigation

Use exception filters with when clauses to route overlapping exception types without deep nesting. Missing files throw the standard System.IO.FileNotFoundException instead of IronBarCodeFileException, so include a separate catch block for this case:

Input

A Code128 barcode encoding an invoice number (success path) and a warehouse label barcode representing the content of the missing PDF (failure path).

Code128 barcode encoding INV-2024-7829 used as the scanned invoice input
Code128 barcode representing the content of the missing warehouse-labels.pdf failure path input
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/exception-hierarchy.cs
using IronBarCode;
using IronBarCode.Exceptions;

// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";

try
{
    BarcodeResults results = BarcodeReader.Read(filePath);
    foreach (BarcodeResult result in results)
    {
        // Print the detected symbology and decoded value for each barcode found
        Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
    }
}
catch (IronBarCodePdfPasswordException ex)
{
    // PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
    Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
    // File is present but corrupted, locked, or in an unsupported format
    Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
    // Missing files throw FileNotFoundException, not IronBarCodeFileException
    Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
    // The when filter routes only missing-DLL errors here; other native exceptions
    // fall through to the IronBarCodeException block below
    Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
    // Base catch for any IronBarcode-specific error not matched by the blocks above
    Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
$vbLabelText   $csharpLabel

Output

Please noteA valid file resolves to the decoded barcode type and value.

Console output showing successful Code128 decode: [Code128] INV-2024-7829

A missing file triggers FileNotFoundException, routed by the dedicated catch block.

Console output showing FileNotFoundException for the missing warehouse-labels.pdf file

The when (ex.Message.Contains("DLL")) filter on IronBarCodeNativeException directs missing-dependency errors to a specific handler without affecting other native exceptions. This approach is especially useful in Docker deployments where platform-specific packages may be missing.

IronSoftware.Exceptions.LicensingException is thrown separately when the license key is invalid or missing. Catch this exception at application startup instead of around individual read or write calls.


How Do I Extract Diagnostic Details from Failed Reads?

A read operation that returns zero results is not an exception; it produces an empty BarcodeResults collection. Diagnostic context is obtained by inspecting input parameters, configured options, and any partial results returned.

The BarcodeResult object provides properties useful for post-mortem analysis, including BarcodeType, Value, PageNumber, and Points (corner coordinates). If results are present but unexpected, first check BarcodeType against the expected format and verify the PageNumber.

Input

A Code128 barcode encoding an invoice number, read with ExpectBarcodeTypes set to Code128 and QRCode, and ReadingSpeed.Detailed for thorough scanning.

Code128 barcode encoding INV-2024-7829 used as the scanned invoice input
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/diagnostic-logging.cs
using IronBarCode;

string filePath = "scanned-invoice.png";

// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
    Speed = ReadingSpeed.Detailed,      // slower but more thorough — use ExtremeDetail for damaged images
    ExpectMultipleBarcodes = true       // scan the full image rather than stopping at the first match
};

BarcodeResults results = BarcodeReader.Read(filePath, options);

// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
    // Log the configured options alongside the warning so the cause is immediately actionable
    Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
    Console.Error.WriteLine($"  ExpectedTypes: {options.ExpectBarcodeTypes}");
    Console.Error.WriteLine($"  Speed: {options.Speed}");
    Console.Error.WriteLine($"  Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
    foreach (BarcodeResult result in results)
    {
        // Points contains the four corner coordinates of the barcode in the image;
        // use the first corner as a representative position indicator
        string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
        Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
            + $"(Page: {result.PageNumber}, Position: {pos})");
    }
}
$vbLabelText   $csharpLabel

Output

Please noteWhen ExpectBarcodeTypes matches the barcode in the image, the read returns the type, value, page number, and position.

Console output showing successful Code128 decode with page number and position coordinates

If ExpectBarcodeTypes does not include the actual symbology, the read returns an empty result. The [WARN] block logs the configured types, reading speed, and a suggested next action.

Console output showing [WARN] no barcodes found with ExpectBarcodeTypes set to Code39 for a Code128 image

Two common patterns emerge during diagnostics. Empty results with a narrow ExpectBarcodeTypes setting often mean the barcode uses a different symbology; expanding to BarcodeEncoding.All can confirm this. Unexpected decode results usually point to poor image quality.

Applying image filters and retrying with a slower reading speed often resolves these issues. You can also toggle the RemoveFalsePositive option to eliminate phantom reads from noisy backgrounds.

How Do I Enable Verbose Logging for Barcode Operations?

IronBarcode exposes a built-in logging API through IronSoftware.Logger. Set the logging mode and file path before any barcode operations to capture internal diagnostic output from the read and write pipelines.

Input

A Code128 barcode TIFF image used as the read target while verbose logging is active.

Code128 barcode encoding PROB-SCAN-999 used as the problem scan input for the logging example
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/enable-logging.cs
using IronBarCode;

// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory

// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Detailed,
    ExpectBarcodeTypes = BarcodeEncoding.All  // scan for every supported symbology
};

BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
$vbLabelText   $csharpLabel

LoggingModes.All captures both debug output and file-level logging. The log file records internal processing steps, such as image pre-processing stages, format detection attempts, and native interop calls, which are not visible through the public API.

For production pipelines using a structured logging framework (Serilog, NLog, Microsoft.Extensions.Logging), wrapping IronBarcode operations in a middleware layer adds structured JSON entries alongside the built-in log file. The built-in logger writes plain-text diagnostics useful for support escalation; the structured wrapper provides queryable fields for the observability stack.

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/structured-wrapper.cs
using IronBarCode;
using System.Diagnostics;

// Lightweight wrapper that adds structured JSON observability to every read call.
// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
BarcodeResults ReadWithDiagnostics(string filePath, BarcodeReaderOptions options)
{
    var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included
    try
    {
        BarcodeResults results = BarcodeReader.Read(filePath, options);
        sw.Stop();
        // Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
        Console.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\","
            + $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
        return results;
    }
    catch (Exception ex)
    {
        sw.Stop();
        // Emit a structured error entry to stderr with exception type, message, and elapsed time
        Console.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\","
            + $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\","
            + $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
        throw; // rethrow so the caller's catch blocks still handle the exception normally
    }
}
$vbLabelText   $csharpLabel

The structured output integrates directly with log aggregation tools. Pipe stdout to Fluentd, Datadog, or CloudWatch in a containerized deployment. The elapsed-time field highlights performance regressions before they become SLA violations.

Output

Console output showing a successful barcode read with verbose logging enabled and the log file path

How Do I Debug Batch Barcode Processing?

Process multiple files by isolating each read in its own try-catch block, recording outcomes for each file, and generating an aggregate summary. The pipeline continues through failures instead of stopping at the first error.

Input

Four of the five Code128 barcode images from the scans/ batch directory. The fifth file (scan-05-broken.png) contains invalid bytes to trigger a file exception.

Code128 barcode encoding ITEM-SQ-001

Batch 1 — Scan 1

Code128 barcode encoding ITEM-SQ-002

Batch 1 — Scan 2

Code128 barcode encoding ITEM-SQ-003

Batch 1 — Scan 3

Code128 barcode encoding ITEM-SQ-004

Batch 1 — Scan 4

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/batch-processing.cs
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;

// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";

// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,                                    // balances throughput vs accuracy
    ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
    ExpectMultipleBarcodes = true                                     // scan each file fully
};

// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();

foreach (string file in files)
{
    try
    {
        BarcodeResults results = BarcodeReader.Read(file, options);

        // Empty result is not an exception — the file was read but contained no matching barcode
        if (results == null || results.Count == 0)
        {
            emptyCount++;
            errors.Add((file, "No barcodes detected")); // record so caller can adjust options
            continue;
        }

        foreach (BarcodeResult result in results)
        {
            Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
        }
        successCount++;
    }
    catch (IronBarCodePdfPasswordException)
    {
        // PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
        failCount++;
        errors.Add((file, "Password-protected PDF"));
    }
    catch (IronBarCodeFileException ex)
    {
        // File is corrupted, locked, or in an unsupported image format
        failCount++;
        errors.Add((file, $"File error: {ex.Message}"));
    }
    catch (FileNotFoundException ex)
    {
        // File was in the directory listing but deleted before the read completed (race condition)
        failCount++;
        errors.Add((file, $"File not found: {ex.Message}"));
    }
    catch (IronBarCodeException ex)
    {
        // Catch-all for any other IronBarcode-specific errors not handled above
        failCount++;
        errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
    }
    catch (Exception ex)
    {
        // Unexpected non-IronBarcode error — log the full type for investigation
        failCount++;
        errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
    }
}

sw.Stop();

// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files:    {files.Length}");
Console.WriteLine($"Success:        {successCount}");
Console.WriteLine($"Empty reads:    {emptyCount}");
Console.WriteLine($"Failures:       {failCount}");
Console.WriteLine($"Elapsed:        {sw.Elapsed.TotalSeconds:F1}s");

if (errors.Any())
{
    Console.WriteLine("\n--- Error Details ---");
    foreach (var (errorFile, errorMsg) in errors)
    {
        Console.Error.WriteLine($"  {Path.GetFileName(errorFile)}: {errorMsg}");
    }
}
$vbLabelText   $csharpLabel

Output

Console output showing the batch summary: 4 successes, 1 failure, with error details for the corrupted file

During execution, the console outputs one line for each decoded barcode, followed by a summary with file count, successes, empty reads, failures, and elapsed time. Errors are listed with their corresponding file names and reasons for failure.

The process distinguishes three outcome categories: success (barcodes found and decoded), empty (file read but no barcodes detected), and failure (exception thrown). This distinction matters because empty reads and failures require different responses. Empty reads may need broader format settings, while failures often indicate infrastructure issues such as missing files, locked resources, or missing native dependencies.

The error list maintains per-file context to support root cause analysis. In a CI/CD pipeline, parse this output to set exit codes (zero for complete success and non-zero when failCount is greater than zero) or forward error details to an alerting system.

For higher throughput, enable parallel processing by setting Multithreaded to true and adjusting MaxParallelThreads to match available CPU cores. Maintain per-file isolation by wrapping the parallel iteration in Parallel.ForEach and using a thread-safe collection for the error list.


Further Reading

View licensing options when the pipeline is ready for production.

Frequently Asked Questions

How can I handle errors in barcode operations using IronBarcode?

IronBarcode provides typed exceptions and built-in logging to efficiently manage and handle errors in barcode operations, ensuring your application runs smoothly.

What features does IronBarcode offer for debugging barcode issues?

IronBarcode includes diagnostic extraction and production-ready batch error isolation, which assist developers in identifying and resolving barcode-related issues efficiently.

Can IronBarcode log errors during barcode processing?

Yes, IronBarcode has built-in logging capabilities that allow developers to capture and log error details during barcode processing, facilitating easier debugging.

What are typed exceptions in IronBarcode?

Typed exceptions in IronBarcode are specific error types that provide detailed information about barcode operation issues, making it easier for developers to diagnose and fix problems.

How does IronBarcode assist with batch error isolation?

IronBarcode offers production-ready batch error isolation, which helps in separating erroneous barcode operations from successful ones, streamlining error management in batch processing.

Is there a way to extract diagnostics from barcode operations using IronBarcode?

Yes, IronBarcode provides diagnostic extraction tools that help developers gather detailed information about barcode operations, aiding in troubleshooting and error resolution.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More
Ready to Get Started?
Nuget Downloads 2,124,798 | Version: 2026.3 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast? PM > Install-Package BarCode
run a sample watch your string become a barcode.