composer/composer · error · PluginBlockedException

{package}{global_suffix} contains a Composer plugin which is

Error message

{package}{global_suffix} contains a Composer plugin which is blocked by your allow-plugins config. You may add it to the list if you consider it safe.
You can run "composer {global_prefix}config --no-plugins allow-plugins.{package} [true|false]" to enable it (true) or disable it explicitly and suppress this exception (false)
See https://getcomposer.org/allow-plugins

What it means

Thrown as PluginBlockedException by PluginManager when a Composer plugin package is not permitted by the 'allow-plugins' config and cannot be authorized interactively. Composer 2.2+ requires explicit opt-in for every plugin package; in non-interactive mode (or after the interactive prompt is exhausted/answered 'discard') the run aborts here.

Source

Thrown at src/Composer/Plugin/PluginManager.php:821

                        return $allow;

                    case '?':
                    default:
                        $attempts++;
                        $this->io->writeError([
                            'y - add package to allow-plugins in composer.json and let it run immediately',
                            'n - add package (as disallowed) to allow-plugins in composer.json to suppress further prompts',
                            'd - discard this, do not change composer.json and do not allow the plugin to run',
                            '? - print help',
                        ]);
                        break;
                }
            }
        } elseif ($optional) {
            return false;
        }

        throw new PluginBlockedException(
            $package.($isGlobalPlugin || $this->runningInGlobalDir ? ' (installed globally)' : '').' contains a Composer plugin which is blocked by your allow-plugins config. You may add it to the list if you consider it safe.'.PHP_EOL.
            'You can run "composer '.($isGlobalPlugin || $this->runningInGlobalDir ? 'global ' : '').'config --no-plugins allow-plugins.'.$package.' [true|false]" to enable it (true) or disable it explicitly and suppress this exception (false)'.PHP_EOL.
            'See https://getcomposer.org/allow-plugins'
        );
    }
}

View on GitHub (pinned to 6ffc117740)

Solutions

  1. Run the exact command from the message: composer config --no-plugins allow-plugins.<package> true (or 'composer global config ...' for global plugins).
  2. Or add the package to config.allow-plugins in composer.json as true.
  3. If you intentionally never want it, set it to false to suppress the exception.
  4. For CI, pre-seed allow-plugins in composer.json so no interactive prompt is needed.

Example fix

// before (composer.json - no allow-plugins)
{
  "require": { "symfony/flex": "^2" }
}
// after
{
  "require": { "symfony/flex": "^2" },
  "config": { "allow-plugins": { "symfony/flex": true } }
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-seed allow-plugins before running composer non-interactively
$ composer config allow-plugins.symfony/flex true
// or assert in PHP before install
$cfg = json_decode(file_get_contents('composer.json'), true);
$plugin = 'symfony/flex';
if (!isset($cfg['config']['allow-plugins'][$plugin])) {
    throw new \RuntimeException('allow-plugins missing '.$plugin);
}

Type guard

function pluginIsAllowed(string $composerJson, string $plugin): bool
{
    $cfg = json_decode((string) file_get_contents($composerJson), true);
    return is_array($cfg) && ($cfg['config']['allow-plugins'][$plugin] ?? false) === true;
}

Try / catch

use Composer\Plugin\PluginBlockedException;
try {
    // run composer operation that loads plugins
} catch (PluginBlockedException $e) {
    fwrite(STDERR, $e->getMessage());
    // parse package from message and add to allow-plugins
}

Prevention

When it happens

Trigger: A dependency that ships a Composer plugin is being installed/loaded, the package is not listed (or is set false) under config.allow-plugins, and either the IO is non-interactive, the prompt was answered 'd' (discard), or the prompt exceeded 5 failed attempts (lines 767-825).

Common situations: Fresh 'composer install' in CI/containers (non-interactive) where composer.json predates allow-plugins; requiring a plugin-providing package (e.g. symfony/flex, composer/ca-bundle-aware tools, phpstan/extension-installer) for the first time; Composer 2.2 upgrade where allow-plugins was retroactively required.

Related errors


AI-assisted analysis of composer/composer@6ffc117740 (2026-08-07). Data as JSON: /api/errors/4f6690f7c1df141f. Report an issue: GitHub.