The Symfony service container decides which objects are built and injected when controllers, console commands, event subscribers, and application services run. Inspecting the compiled container helps when a type-hint receives an unexpected service, a tagged class is missing, or a custom service is not visible from bin/console.
The debug:container command reads the container for one environment and shows service IDs, aliases, tags, constructor arguments, and usages. The debug:autowiring command is the clearer view when the question is which class or interface to type-hint, or which #[Target] variant Symfony will inject.
Run the checks from the project root that contains bin/console. Use the same environment as the failure, because dev, test, and prod can load different bundles, configuration blocks, debug wrappers, and optimized services.
Related: How to create a Symfony project
Related: How to create a Symfony console command
Related: How to enable the Symfony profiler
Steps to debug the Symfony service container:
- Open a terminal in the Symfony project root.
- Confirm the console environment that will be inspected.
$ php bin/console about -------------------- --------------------------------- Symfony -------------------- --------------------------------- Version v8.1.0 Environment dev Debug true -------------------- --------------------------------- PHP -------------------- --------------------------------- Version 8.4.22 OPcache Enabled -------------------- ---------------------------------
Pass --env=prod, --env=test, or --no-debug to the later debug commands when the failing behavior appears outside the default dev container.
- Search for the service ID, alias, or short term from the error message.
$ php bin/console debug:container mailer // This service is a private alias for the service mailer.mailer Information for Service "mailer.mailer" ======================================= ---------------- --------------------------------------------- Option Value ---------------- --------------------------------------------- Service ID mailer.mailer Class Symfony\Component\Mailer\Mailer Public no Arguments Service(mailer.transports) Service(debug.traced.messenger.bus.default) Service(debug.event_dispatcher) Usages mailer Symfony\Component\Mailer\MailerInterface ---------------- --------------------------------------------- ! [NOTE] The "mailer" service or alias has been removed or inlined when the ! container was compiled.The alias line, Class, Arguments, and Usages fields identify what Symfony will build or inject. A removed-or-inlined note is common for private optimized services and is not by itself a registration failure.
- Check the autowiring type-hints when a constructor receives the wrong dependency.
$ php bin/console debug:autowiring logger Autowirable Types ================= Use the following classes & interfaces as type-hints in constructor arguments to autowire services. Add #[Target('name')] to the argument to select a specific variant. (only showing classes/interfaces matching logger) Psr\Log\LoggerInterface -> monolog.logger Describes a logger instance. #[Target('asset_mapper')] -> monolog.logger.asset_mapper #[Target('cache')] -> monolog.logger.cache #[Target('console')] -> monolog.logger.console #[Target('debug')] -> monolog.logger.debug #[Target('deprecation')] -> monolog.logger.deprecation #[Target('doctrine')] -> monolog.logger.doctrine #[Target('event')] -> monolog.logger.event #[Target('http_client')] -> monolog.logger.http_client #[Target('mailer')] -> monolog.logger.mailer ##### snipped #####Use the plain interface when the default service is correct. Use #[Target('mailer')] or another listed target when the constructor needs a named variant.
- List services for the tag when autoconfiguration or event registration is the suspected layer.
$ php bin/console debug:container --tag=kernel.event_subscriber Symfony Container Services Tagged with "kernel.event_subscriber" Tag ==================================================================== ----------------------------------------------------------------------- -------------------------------------- --------------------------------------------------------------------------------------- Service ID dispatcher Class name ----------------------------------------------------------------------- -------------------------------------- --------------------------------------------------------------------------------------- console.error_listener Symfony\Component\Console\EventListener\ErrorListener argument_resolver.request_payload Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver response_listener Symfony\Component\HttpKernel\EventListener\ResponseListener locale_listener Symfony\Component\HttpKernel\EventListener\LocaleListener validate_request_listener Symfony\Component\HttpKernel\EventListener\ValidateRequestListener ##### snipped ##### web_profiler.debug_toolbar Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener controller.is_granted_attribute_listener Symfony\Component\Security\Http\EventListener\IsGrantedAttributeListener security.listener.check_authenticator_credentials Symfony\Component\Security\Http\EventListener\CheckCredentialsListener ----------------------------------------------------------------------- -------------------------------------- ---------------------------------------------------------------------------------------
Replace kernel.event_subscriber with the tag named in the error, bundle documentation, or expected autoconfiguration path, such as console.command, messenger.message_handler, or twig.extension.
- Inspect the application service loading rules when a class under src/ is missing.
$ cat config/services.yaml # yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json parameters: services: # default configuration for services in *this* file _defaults: autowire: true # Automatically injects dependencies in your services. autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. # makes classes in src/ available to be used as services # this creates a service per class whose id is the fully-qualified class name App\: resource: '../src/' # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous onesIf the class is outside the loaded resource path, excluded by a later rule, or overridden by a later definition, adjust the service configuration before searching the container again.
- Re-run an exact service or type-hint lookup after choosing the ID to use in code or configuration.
$ php bin/console debug:container Psr\\Log\\LoggerInterface // This service is a private alias for the service monolog.logger Information for Service "monolog.logger" ======================================== Monolog log channel ---------------- ---------------------------------------------------- Option Value ---------------- ---------------------------------------------------- Service ID monolog.logger Class Monolog\Logger Tags monolog.channel_logger Calls useMicrosecondTimestamps, pushHandler, pushHandler Public no Arguments app Usages logger Psr\Log\LoggerInterface error_handler.error_renderer.html asset_mapper.compressor doctrine.migrations.dependency_factory ---------------- ----------------------------------------------------
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.