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

  1. Include the host in the filesystem URI, e.g. ftp://myftpserver/path
  2. Or set the Hadoop config fs.ftp.host to the server name before obtaining the filesystem
  3. 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

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/9a4bdce703f24f26. Report an issue: GitHub.