{"record":{"id":"a16cf4c64aacb027","repo":"thephpleague/flysystem","slug":"could-not-set-passive-mode-for-connection-host","errorCode":null,"errorMessage":"Could not set passive mode for connection: {host}::{port}","messagePattern":"Could not set passive mode for connection: (.+?)::(.+?)","errorType":"exception","errorClass":"UnableToMakeConnectionPassive","httpStatus":null,"severity":"error","filePath":"src/Ftp/FtpConnectionProvider.php","lineNumber":105,"sourceCode":"    {\n        $ignorePassiveAddress = $options->ignorePassiveAddress();\n\n        if ( ! is_bool($ignorePassiveAddress) || ! defined('FTP_USEPASVADDRESS')) {\n            return;\n        }\n\n        if ( ! @ftp_set_option($connection, FTP_USEPASVADDRESS, ! $ignorePassiveAddress)) {\n            throw UnableToSetFtpOption::whileSettingOption('FTP_USEPASVADDRESS');\n        }\n    }\n\n    /**\n     * @param resource $connection\n     */\n    private function makeConnectionPassive(FtpConnectionOptions $options, $connection): void\n    {\n        if ( ! @ftp_pasv($connection, $options->passive())) {\n            throw new UnableToMakeConnectionPassive(\n                'Could not set passive mode for connection: ' . $options->host() . '::' . $options->port()\n            );\n        }\n    }\n}\n","sourceCodeStart":87,"sourceCodeEnd":111,"githubUrl":"https://github.com/thephpleague/flysystem/blob/b277b5dc3d56650b68904117124e79c851e12376/src/Ftp/FtpConnectionProvider.php#L87-L111","documentation":"FtpConnectionProvider::makeConnectionPassive() calls ftp_pasv() with the 'passive' option value; if the FTP extension reports failure, UnableToMakeConnectionPassive is thrown with 'Could not set passive mode for connection: host::port'. ftp_pasv only sets the transfer-mode preference, but it fails when the connection is broken or the server rejects the PASV setup during handshake, and Flysystem treats it as fatal.","triggerScenarios":"First file operation after connect when passive = true and the server/firewall interferes with the PASV command (some servers reject PASV before authentication or when data connections are blocked); the control connection dropped between login and pasv; ftp_pasv returning false on servers behind broken NAT.","commonSituations":"Firewalls between app and FTP server blocking the passive data port range; servers that require active mode (passive = false) but the option was left true; containerized apps where the FTP module cannot negotiate data connections.","solutions":["Open the server's passive port range (e.g. 50000-51000) in the FTP server config AND the firewall, and set matching PassivePortRange on the server.","If the server/network requires active mode, set 'passive' => false in FtpConnectionOptions.","Verify basic PASV transfers with an FTP CLI client from the same host/network namespace to isolate app vs environment.","Catch UnableToMakeConnectionPassive and retry once — transient control-connection drops can surface here."],"exampleFix":"// before\n$options = FtpConnectionOptions::lazy('ftp.example.com', '/', FTP_NATIVE, null, 'u', 'p', null, true /* passive */);\n$filesystem->read('file.txt'); // ftp_pasv fails -> throws\n\n// after (active mode environment)\n$options = FtpConnectionOptions::lazy('ftp.example.com', '/', FTP_NATIVE, null, 'u', 'p', null, false /* active */);","handlingStrategy":"retry","validationCode":"// No in-code pre-check possible for ftp_pasv, but you can pre-flight connectivity:\n// ensure the server's passive port range is reachable from the app host\n$socket = @fsockopen($host, 50000, $errno, $errstr, 3); // first port of the declared range\nif ($socket === false) {\n    // passive data channel blocked: fix firewall/NAT before runtime failures\n}\nfclose($socket);","typeGuard":null,"tryCatchPattern":"use League\\Flysystem\\Ftp\\UnableToMakeConnectionPassive;\n\n$maxAttempts = 2;\nfor ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {\n    try {\n        return $filesystem->read($path);\n    } catch (UnableToMakeConnectionPassive $e) {\n        if ($attempt === $maxAttempts) {\n            // persistent: likely firewall/active-mode mismatch — switch strategy, don't loop\n            $options = FtpConnectionOptions::lazy($host, '/', FTP_NATIVE, null, $user, $pass, null, false);\n            $filesystem = new Filesystem(new FtpAdapter($options));\n        }\n    }\n}","preventionTips":["Align the server's passive port range with firewall rules in both directions.","Document whether each FTP target needs active or passive mode and set the option explicitly.","FtpAdapter reconnects on failure — a persistent pasv failure usually means network policy, not bad luck."],"tags":["php","flysystem","ftp","passive-mode","firewall","nat"],"backgroundTag":"ftp-passive-mode-failed","analyzedSha":"b277b5dc3d56650b68904117124e79c851e12376","analyzedAt":"2026-08-17T04:28:35.741Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}