apache/seatunnel · error · IOException

Invalid user/password specified

Error message

Invalid user/password specified

What it means

SeaTunnelFTPFileSystem.initialize() derives credentials from the URI userinfo; when absent it reads fs.ftp.user.<host> and fs.ftp.password.<host> from the Hadoop configuration. If no URI userinfo exists and either the user or password config is null, it throws IOException('Invalid user/password specified').

Source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:116

        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;
        }
        String[] userPasswdInfo = userAndPassword.split(":");
        conf.set(FS_FTP_USER_PREFIX + host, userPasswdInfo[0]);
        if (userPasswdInfo.length > 1) {
            conf.set(FS_FTP_PASSWORD_PREFIX + host, userPasswdInfo[1]);
        } else {
            conf.set(FS_FTP_PASSWORD_PREFIX + host, null);
        }
        setConf(conf);
        this.uri = uri;
    }

    /**
     * Connect to the FTP server using configuration parameters *
     *
     * @return An FTPClient instance

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Embed credentials in the URI: ftp://user:password@ftp.example.com/path
  2. Or set both conf keys fs.ftp.user.<host> and fs.ftp.password.<host> with <host> exactly matching the URI host
  3. Ensure the password does not break the user:password split (avoid ':' or URI-encode it)

Example fix

// before
path = "ftp://ftp.example.com/data" // no credentials anywhere
// after
path = "ftp://user:password@ftp.example.com/data"
// or: conf.set("fs.ftp.user.ftp.example.com", "user"); conf.set("fs.ftp.password.ftp.example.com", "password");
Defensive patterns

Strategy: validation

Validate before calling

// Java
URI uri = URI.create(path);
boolean hasUserInfo = uri.getUserInfo() != null;
String host = uri.getHost() != null ? uri.getHost() : conf.get("fs.ftp.host");
boolean hasConfCreds = conf.get("fs.ftp.user." + host) != null
    && conf.get("fs.ftp.password." + host) != null;
if (!hasUserInfo && !hasConfCreds) {
    throw new IllegalArgumentException("Provide ftp user:pass in URI or fs.ftp.user/password." + host);
}

Try / catch

try {
    fileSystem.initialize(uri, conf);
} catch (IOException e) {
    if ("Invalid user/password specified".equals(e.getMessage())) {
        throw new IllegalArgumentException("Missing FTP credentials for host " + host, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling initialize() with a URI without user info (no user:pass@host) while fs.ftp.user.<host> or fs.ftp.password.<host> is not set in the Configuration; host here is the URI host or the fs.ftp.host fallback.

Common situations: Credentials omitted from the SeaTunnel FTP source/sink config; config keys written with the wrong host suffix (must match exactly, e.g. fs.ftp.user.ftp.example.com); URI-encoded password containing ':' mis-split later; anonymous FTP attempted without explicit user/password entries.

Related errors


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