symfony/process · error · BadMethodCallException

Cannot unserialize Symfony\Component\Process\Pipes\UnixPipes

Error message

Cannot unserialize Symfony\Component\Process\Pipes\UnixPipes

What it means

The counterpart of __serialize: unserializing data into a UnixPipes instance would fabricate an object referencing nonexistent OS resources, so __unserialize() unconditionally throws BadMethodCallException.

Solutions

  1. Remove the offending entry from the serialized payload and recreate the Process instead
  2. Sanitize/unserialize with allowed_classes restrictions so pipes classes are rejected cleanly
  3. Regenerate the cache/session data after upgrading code that previously stored live Process objects

Example fix

// before
$data = unserialize($blob);
// after
$data = unserialize($blob, ['allowed_classes' => false]);
Defensive patterns

Strategy: type-guard

Validate before calling

$data = unserialize($blob, ['allowed_classes' => false]);

Type guard

function safeUnserialize(string $blob): mixed { return unserialize($blob, ['allowed_classes' => false]); }

Try / catch

try { $obj = unserialize($blob); } catch (\BadMethodCallException $e) { $obj = null; }

Prevention

When it happens

Trigger: unserialize() of a payload that contains a UnixPipes object (e.g. a payload crafted or stored when serialization was previously allowed, or attacker-supplied serialized data).

Common situations: Deserializing cached/session data that embedded a Process object; processing untrusted serialized blobs containing pipe objects.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of symfony/process@99b85026db (2026-09-14). Data as JSON: /api/errors/c8f051123ddfa093. Report an issue: GitHub.

Appendix: source

Thrown at Pipes/UnixPipes.php:41

class UnixPipes extends AbstractPipes
{
    public function __construct(
        private ?bool $ttyMode,
        private bool $ptyMode,
        mixed $input,
        private bool $haveReadSupport,
    ) {
        parent::__construct($input);
    }

    public function __serialize(): array
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __unserialize(array $data): void
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        $this->close();
    }

    public function getDescriptors(): array
    {
        if (!$this->haveReadSupport) {
            $nullstream = fopen('/dev/null', 'c');

            return [
                ['pipe', 'r'],
                $nullstream,
                $nullstream,
            ];
        }

View on GitHub (pinned to 99b85026db)