Skip to content

Troubleshoot the NextPDF Symfony bundle

Most issues come from one of four areas: discovery, configuration validation, container wiring, or Messenger routing. Each section pairs a symptom with the bundle behavior behind it, then gives you a console command to confirm the fix.

Symptom: You cannot autowire PdfFactory, or debug:container nextpdf returns nothing.

Cause: the bundle was not added to config/bundles.php. Flex may not have run, or the application may not use Flex.

Resolve:

Terminal window
php bin/console debug:container nextpdf

If the command returns no services, add the bundle manually:

return [
NextPDF\Symfony\NextPdfBundle::class => ['all' => true],
];

The bundle composer.json contains the auto-registration hint under extra.symfony.bundles. It applies only to Flex-enabled applications.

Symptom: the kernel throws a RuntimeException that mentions ext-mbstring or ext-zlib at boot.

Cause: this comes from NextPdfExtension::guardRequiredExtensions(), the bundle’s deliberate fail-fast guard. It is not a defect.

Resolve: enable the named extension in php.ini, then restart the runtime. Confirm with:

Terminal window
php -m | grep -E 'mbstring|zlib'

Symptom: Symfony throws a Symfony\Component\Config\Definition\Exception\InvalidConfigurationException during cache:clear or cache:warmup.

Cause: a value falls outside the schema. Configuration.php defines these constraints:

  • page_format must be one of A4, A3, A5, Letter, Legal, Tabloid.
  • orientation must be P or L.
  • unit must be one of pt, mm, cm, in.
  • pdfa must be null, 4, 4e, or 4f.
  • image_cache_mb must be >= 0.

Resolve: print the merged configuration, then correct the key that failed:

Terminal window
php bin/console debug:config nextpdf

Symptom: pdfa or the signature section is set, but the output is an ordinary Portable Document Format (PDF) file.

Cause: these capabilities require nextpdf/premium. At compile time, PdfFactory applies PDF/A only when it detects the Pro extension. The compiler pass registers a signer only when signature.enabled is true and signature.certificate is set.

Resolve: confirm that Premium is installed and that the signer service exists:

Terminal window
composer show nextpdf/premium
php bin/console debug:container --show-private | grep -i signer

If Premium is absent, the bundle stores the configuration but intentionally leaves it inert. The bundle’s documented signing capability with Pro is the baseline B-B profile. The NextPDF Premium documentation covers profiles beyond B-B.

Symptom: the artisan configuration is ignored.

Cause: Chrome DevTools Protocol (CDP) rendering requires nextpdf/artisan. The compiler pass probes for it with class_exists at compile time. If the extension is absent, the renderer is not wired.

Resolve:

Terminal window
composer show nextpdf/artisan
php bin/console cache:clear # re-run the compile-time probe

The probe runs during container compilation. After you install the extension, run a fresh cache:clear.

Symptom: You dispatch GeneratePdfMessage, but no PDF is written.

Causes and resolutions:

  • Message not routed — add a routing entry that maps NextPDF\Symfony\Message\GeneratePdfMessage to a transport in config/packages/messenger.yaml, then run a worker (php bin/console messenger:consume <transport>).
  • Builder not in the locator — the handler fetches the builder from a PHP Standards Recommendation 11 (PSR-11) locator by its class-string id. A container identifier is a string that uniquely identifies an entry (PSR-11 §1.1.2). If the locator does not have the builder class registered, the handler raises a RuntimeException saying the configured builder must implement PdfBuilderInterface. Register the builder, then reference it from the locator.

Inspect routing and the locator:

Terminal window
php bin/console debug:messenger
php bin/console debug:container --tag=container.service_locator

Message rejected at dispatch with InvalidArgumentException

Section titled “Message rejected at dispatch with InvalidArgumentException”

Symptom: constructing GeneratePdfMessage throws an InvalidArgumentException.

Cause: the message data transfer object (DTO) validates its inputs. The verified rejection rules are:

  • empty output path, or one containing a null byte;
  • a stream-wrapper scheme (for example php://...);
  • a .. path-traversal segment (POSIX or Windows separators);
  • an output path not ending in .pdf (case-insensitive);
  • a builderClass that is not a syntactically valid class name.

Resolve: pass an absolute filesystem path that ends in .pdf and a real fully qualified builder class name.

Symptom: a generated PDF includes content from a previous request.

Cause: a long-running worker held a Document instance across requests. The document service is non-shared precisely to prevent this.

Resolve: call PdfFactory::create() inside the request-scoped method. Never store the returned document on a shared service.

Terminal window
php bin/console debug:container nextpdf # bundle services
php bin/console debug:config nextpdf # merged configuration
php bin/console debug:container --show-private # internal definitions
php bin/console debug:messenger # message routing
php bin/console messenger:consume <t> -vv # verbose consume

Each row is a normative claim made on this page and is pinned to a full 64-hex reference_id from the gated standards development organization (SDO) corpus. Provenance, including the corpus manifest and the retrieval transport, is in _sidecars/rag-citations.yaml.

SpecClausereference_idClaim
PSR-11psr_11_container#1.1.2.p4Container has()/get() identifier contract
  • /integrations/symfony/install/ — installation and registration.
  • /integrations/symfony/configuration/ — full schema and constraints.
  • /integrations/symfony/boot-and-discovery/ — discovery and boot sequence.
  • /integrations/symfony/security-and-operations/ — security headers and path validation.