Skip to content

Troubleshooting NextPDF on CodeIgniter 4

Each symptom below maps to a verified cause in the package or framework source and includes a concrete fix.

When CodeIgniter resolves a service, it scans the discovered Config\Services classes for a matching method. A null return means CodeIgniter did not discover the package’s Services class.

Check these causes and fixes:

  • Auto-discovery is disabled. The host application may set Config\Modules::$discoverInComposer = false. If so, add nextpdf/codeigniter to $composerPackages['only']. CodeIgniter scans Composer packages only when this flag is true.
  • The autoloader is stale. Composer maps the namespace prefix NextPDF\CodeIgniter\ to its base directory. A stale classmap hides the class (PSR-4 §x1.x3). Run composer dump-autoload.
  • The $aliases list was trimmed. Discovery runs only for the entries in Config\Modules::$aliases. The package needs services and, for helpers, registrars. Restore both entries.

The helpers load through two routes: the package Composer files autoload entry and the package Registrar. An undefined-function error means the files entry did not load.

  • Run composer dump-autoload to rebuild the files autoload list.
  • Confirm that nextpdf/codeigniter appears in vendor/composer/autoload_files.php.
  • If you need a workaround, call Services::pdf(false) or Services::pdfDocument(false) directly. The helpers are thin wrappers around these calls.

To resolve an override, BaseConfig uses the lowercase short class name as the prefix. Because the class is NextPdf, the prefix is nextpdf. It is not nextPdf or NextPdf.

  • Use nextpdf.fontsPath, not nextPdf.fontsPath.
  • For a nested key, use a dot: nextpdf.signature.certificate.
  • The fully qualified form NextPDF\CodeIgniter\Config\NextPdf.fontsPath also works.

When you extend the NextPdf class and assign a partial array, CodeIgniter replaces the whole array. Provide every key in the array you override. For a full-array example, see /integrations/codeigniter/configuration/.

RuntimeException: NextPDF requires the ext-… PHP extension

Section titled “RuntimeException: NextPDF requires the ext-… PHP extension”

The font registry validates mbstring and zlib once per process. It raises this error with the missing extension name. Install or enable the named extension in the runtime PHP, then restart the worker or PHP FastCGI Process Manager (PHP-FPM) pool.

RuntimeException: NextPdf fontsPath contains invalid characters

Section titled “RuntimeException: NextPdf fontsPath contains invalid characters”

The font registry rejects a fontsPath that contains a stream wrapper (://) or a null byte. Set fontsPath to a plain file system path. Do not point it at a php://, phar://, or similar wrapped path.

PdfResponse sanitizes filenames. Expect this verified behavior:

  • An empty or whitespace-only filename becomes document.pdf.
  • A name without a .pdf (or .PDF) extension gets .pdf appended. An existing .PDF is preserved as-is.
  • A name with non-ASCII characters produces an ASCII fallback and an RFC 5987 filename*=UTF-8''… parameter, so modern browsers show the original name. This is expected, not a bug.
  • Path separators, null bytes, and carriage return/line feed (CR/LF) are stripped.

Every PdfResponse includes X-Content-Type-Options, X-Frame-Options, Content-Security-Policy, X-Robots-Tag, and Referrer-Policy. If they are absent at the client, a proxy or the application is stripping or overwriting them downstream. Inspect the response both before and after your reverse proxy.

The queue checks the pushed job name against the keys in Config\Queue::$jobHandlers and rejects any name that is not registered. Register the job under a name key, then push that name:

app/Config/Queue.php
public array $jobHandlers = ['generate-pdf' => GeneratePdfJob::class];
// dispatch
\service('queue')->push('pdf-queue', 'generate-pdf', [...]);

Pushing GeneratePdfJob::class as the job name fails. The second argument is a name key, not a class string.

The job validates its payload before doing any work. These verified rejection cases return these message fragments:

CauseMessage fragment
builder missing, empty, or not a stringnon-empty static callable string
builder outside App\PdfBuildersnot allowed
builder matches the pattern but is not callablenot a valid callable
outputPath missing or emptynon-empty string
outputPath outside WRITEPATH/pdfs/outside of allowed directory
outputPath not ending in .pdfmust end with .pdf

Fix the payload so the builder is an App\PdfBuilders\<Class>::<method> static callable. Make sure the output path resolves inside WRITEPATH/pdfs/ with a .pdf extension.

Because codeigniter4/queue is a development-only dependency of the package, the application that runs workers must require it directly:

Terminal window
composer require codeigniter4/queue
  • composer show nextpdf/codeigniter — confirm Composer resolved the package.
  • composer dump-autoload — rebuild discovery and the helper autoload list.
  • php spark routes — confirm your PDF routes are registered.
  • For the fastest discovery check, use a controller that calls Services::pdfDocument(false) and asserts the result is a Document.
  • Class-to-path mapping — relevant to discovery failures (PSR-4 Autoloader §x1.x3).
  • /integrations/codeigniter/install/ — requirements for discovery.
  • /integrations/codeigniter/configuration/ — the .env prefix and array-override rule.
  • /integrations/codeigniter/production-usage/ — correct queue registration.
  • /integrations/codeigniter/boot-and-discovery/ — the discovery sequence.