thephpleague/flysystem · error · UnableToMakeConnectionPassive
Could not set passive mode for connection: {host}::{port}
Error message
Could not set passive mode for connection: {host}::{port} What it means
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.
Source
Thrown at src/Ftp/FtpConnectionProvider.php:105
{
$ignorePassiveAddress = $options->ignorePassiveAddress();
if ( ! is_bool($ignorePassiveAddress) || ! defined('FTP_USEPASVADDRESS')) {
return;
}
if ( ! @ftp_set_option($connection, FTP_USEPASVADDRESS, ! $ignorePassiveAddress)) {
throw UnableToSetFtpOption::whileSettingOption('FTP_USEPASVADDRESS');
}
}
/**
* @param resource $connection
*/
private function makeConnectionPassive(FtpConnectionOptions $options, $connection): void
{
if ( ! @ftp_pasv($connection, $options->passive())) {
throw new UnableToMakeConnectionPassive(
'Could not set passive mode for connection: ' . $options->host() . '::' . $options->port()
);
}
}
}
View on GitHub (pinned to b277b5dc3d)
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.
Example fix
// before
$options = FtpConnectionOptions::lazy('ftp.example.com', '/', FTP_NATIVE, null, 'u', 'p', null, true /* passive */);
$filesystem->read('file.txt'); // ftp_pasv fails -> throws
// after (active mode environment)
$options = FtpConnectionOptions::lazy('ftp.example.com', '/', FTP_NATIVE, null, 'u', 'p', null, false /* active */); Defensive patterns
Strategy: retry
Validate before calling
// No in-code pre-check possible for ftp_pasv, but you can pre-flight connectivity:
// ensure the server's passive port range is reachable from the app host
$socket = @fsockopen($host, 50000, $errno, $errstr, 3); // first port of the declared range
if ($socket === false) {
// passive data channel blocked: fix firewall/NAT before runtime failures
}
fclose($socket); Try / catch
use League\Flysystem\Ftp\UnableToMakeConnectionPassive;
$maxAttempts = 2;
for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
try {
return $filesystem->read($path);
} catch (UnableToMakeConnectionPassive $e) {
if ($attempt === $maxAttempts) {
// persistent: likely firewall/active-mode mismatch — switch strategy, don't loop
$options = FtpConnectionOptions::lazy($host, '/', FTP_NATIVE, null, $user, $pass, null, false);
$filesystem = new Filesystem(new FtpAdapter($options));
}
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Metadata can't be parsed from item '$item' , not enough part
- Unable to login/authenticate with FTP
- Could not set UTF-8 mode for connection: {host}::{port}
- Unable to get checksum for $path: $reason
- ETag header not available.
AI-assisted analysis of thephpleague/flysystem@b277b5dc3d (2026-08-17).
Data as JSON: /api/errors/a16cf4c64aacb027.
Report an issue: GitHub.