apache/hadoop · error · IOException
Login failed on server - {host}, port - {port} as user '{use
Error message
Login failed on server - {host}, port - {port} as user '{user}' What it means
The TCP connection and control-channel greeting succeeded (positive completion reply), but FTPClient.login(user, password) returned false — the server rejected the credentials. FTPFileSystem takes user/password from the URI userinfo or from the fs.ftp.user.<host> / fs.ftp.password.<host> keys (note the host suffix).
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPFileSystem.java:162
String host = conf.get(FS_FTP_HOST);
int port = conf.getInt(FS_FTP_HOST_PORT, FTP.DEFAULT_PORT);
String user = conf.get(FS_FTP_USER_PREFIX + host);
String password = conf.get(FS_FTP_PASSWORD_PREFIX + host);
client = new FTPClient();
client.connect(host, port);
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw NetUtils.wrapException(host, port,
NetUtils.UNKNOWN_HOST, 0,
new ConnectException("Server response " + reply));
} else if (client.login(user, password)) {
client.setFileTransferMode(getTransferMode(conf));
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setBufferSize(DEFAULT_BUFFER_SIZE);
setTimeout(client, conf);
setDataConnectionMode(client, conf);
} else {
throw new IOException("Login failed on server - " + host + ", port - "
+ port + " as user '" + user + "'");
}
return client;
}
/**
* Set the FTPClient's timeout based on configuration.
* FS_FTP_TIMEOUT is set as timeout (defaults to DEFAULT_TIMEOUT).
*/
@VisibleForTesting
void setTimeout(FTPClient client, Configuration conf) {
long timeout = conf.getLong(FS_FTP_TIMEOUT, DEFAULT_TIMEOUT);
client.setControlKeepAliveTimeout(timeout);
}
/**
* Set FTP's transfer mode based on configuration. Valid values areView on GitHub (pinned to 2add963021)
Solutions
- Verify credentials outside Hadoop first: curl -u user:pass ftp://host/ or lftp ftp://user@host
- Set credentials explicitly with the correct host suffix: conf.set("fs.ftp.user." + host, user) and conf.set("fs.ftp.password." + host, password)
- Avoid embedding passwords with ':' or '@' in the URI userinfo; use the config keys instead
- Check whether the account is locked/expired or the server requires a specific auth mechanism
Example fix
// before
conf.set("fs.ftp.host", "ftp.example.com");
conf.set("fs.ftp.user.ftp.example.com", "alice");
conf.set("fs.ftp.password.example.com", "secret"); // wrong suffix -> login fails
// after
conf.set("fs.ftp.host", "ftp.example.com");
conf.set("fs.ftp.user.ftp.example.com", "alice");
conf.set("fs.ftp.password.ftp.example.com", "secret"); Defensive patterns
Strategy: try-catch
Validate before calling
// preflight credentials with a raw client before running the job
try (FTPClient probe = new FTPClient()) {
probe.connect(host, port);
if (!probe.login(user, password)) {
throw new IllegalArgumentException("FTP credentials rejected for " + user);
}
probe.logout();
} Try / catch
try {
fs = path.getFileSystem(conf);
fs.open(someFile);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Login failed")) {
// fail fast with actionable message instead of retrying
throw new IOException("FTP login rejected - check fs.ftp.user.<host>/fs.ftp.password.<host>", e);
}
throw e;
} Prevention
- Keep the host suffix consistent across fs.ftp.host, fs.ftp.user.<host> and fs.ftp.password.<host>
- Prefer config keys over URI userinfo when passwords contain ':' or '@'
- Preflight the login once at job start rather than discovering it per operation
When it happens
Trigger: Every filesystem operation calls connect(); wrong user or password, expired/locked account, or credentials read from the wrong config key (host suffix mismatch) all end here. Note initialize() requires both user and password non-null (it splits userinfo on ':' and requires two parts).
Common situations: Password rotated on the FTP server but not in job config; fs.ftp.user.<host> configured with a different host string than fs.ftp.host; passwords containing ':' or '@' breaking the URI userinfo split; server disallowing anonymous logins.
Related errors
- No COS Credential Providers
- SimpleAWSCredentialsProvider: No AWS credentials in the Hado
- Session credentials in Hadoop configuration: No AWS Credenti
- {component}: No AWS credentials
- {component}: Invalid AWS credentials in {credentials} requir
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/322fbe8dcc4893b3.
Report an issue: GitHub.