apache/seatunnel · error · IOException
Invalid host specified
Error message
Invalid host specified
What it means
SeaTunnelFTPFileSystem.initialize() resolves the FTP host from the filesystem URI, falling back to the fs.ftp.host Hadoop config. If neither the URI contains a host nor the config provides one, it throws IOException('Invalid host specified') because an FTP filesystem cannot be created without a target server.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:101
* Return the protocol scheme for the FileSystem.
*
* <p>
*
* @return <code>ftp</code>
*/
@Override
public String getScheme() {
return "ftp";
}
@Override
public void initialize(URI uri, Configuration conf) throws IOException { // get
super.initialize(uri, conf);
// get host information from uri (overrides info in conf)
String host = uri.getHost();
host = (host == null) ? conf.get(FS_FTP_HOST, null) : host;
if (host == null) {
throw new IOException("Invalid host specified");
}
conf.set(FS_FTP_HOST, host);
// get port information from uri, (overrides info in conf)
int port = uri.getPort();
port = (port == -1) ? FTP.DEFAULT_PORT : port;
conf.setInt("fs.ftp.host.port", port);
// get user/password information from URI (overrides info in conf)
String userAndPassword = uri.getUserInfo();
if (userAndPassword == null) {
String user = conf.get("fs.ftp.user." + host, null);
String password = conf.get("fs.ftp.password." + host, null);
if (user == null || password == null) {
throw new IOException("Invalid user/password specified");
}
userAndPassword = user + ":" + password;
}View on GitHub (pinned to cf67b549a7)
Solutions
- Include the host in the filesystem URI, e.g. ftp://myftpserver/path
- Or set the Hadoop config fs.ftp.host to the server name before obtaining the filesystem
- Verify the full path string in the SeaTunnel source/sink config is a well-formed ftp:// URI with a host
Example fix
// before path = "ftp:///data/files" // after path = "ftp://ftp.example.com/data/files"
Defensive patterns
Strategy: validation
Validate before calling
// Java
URI uri = URI.create(path);
if (!"ftp".equals(uri.getScheme()) || uri.getHost() == null) {
throw new IllegalArgumentException("FTP path must include host, e.g. ftp://host/path, got: " + path);
} Try / catch
try {
fileSystem.initialize(uri, conf);
} catch (IOException e) {
if ("Invalid host specified".equals(e.getMessage())) {
throw new IllegalArgumentException("Set host in URI or fs.ftp.host config", e);
}
throw e;
} Prevention
- Always use fully qualified ftp://host/path URIs in configs
- Render config templates before submission (no leftover ${host} placeholders)
- Sanity-parse the URI with URI.create and check getHost() != null in a preflight step
When it happens
Trigger: Constructing/getting the FTP filesystem with a URI lacking a host (e.g. 'ftp:///') while conf.get(FS_FTP_HOST) is also null — e.g. path 'ftp://' or a URI built from a bare path without the ftp:// scheme/host part.
Common situations: SeaTunnel config 'fs.default-fs' or file path missing the host component; host supplied only under a wrong config key; template path left unrendered (e.g. '${host}' not substituted).
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Invalid user/password specified
- Unknown ftp connection mode: ${mode}
- Path ${file} is a directory.
- Unable to open file: ${file}, Aborting
- File already exists: ${file}
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/9a4bdce703f24f26.
Report an issue: GitHub.