apache/seatunnel · error · IllegalStateException

No user specified for sftp connection. Expand URI or credent

Error message

No user specified for sftp connection. Expand URI or credential file.

What it means

setConfigurationFromURI resolves the SFTP username from the URI user info or credential properties (fs.sftp.user.<host>); if none is found it throws IllegalStateException with E_USER_NULL: "No user specified for sftp connection. Expand URI or credential file." Authentication is impossible without a user, so setup aborts.

Source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPFileSystem.java:118

        int port = uriInfo.getPort();
        port = (port == -1) ? conf.getInt(FS_SFTP_HOST_PORT, DEFAULT_SFTP_PORT) : port;
        conf.setInt(FS_SFTP_HOST_PORT, port);

        // get user/password information from URI
        String userAndPwdFromUri = uriInfo.getUserInfo();
        if (userAndPwdFromUri != null) {
            String[] userPasswdInfo = userAndPwdFromUri.split(":");
            String user = userPasswdInfo[0];
            user = URLDecoder.decode(user, "UTF-8");
            conf.set(FS_SFTP_USER_PREFIX + host, user);
            if (userPasswdInfo.length > 1) {
                conf.set(FS_SFTP_PASSWORD_PREFIX + host + "." + user, userPasswdInfo[1]);
            }
        }

        String user = conf.get(FS_SFTP_USER_PREFIX + host);
        if (user == null || user.equals("")) {
            throw new IllegalStateException(E_USER_NULL);
        }

        int connectionMax = conf.getInt(FS_SFTP_CONNECTION_MAX, DEFAULT_MAX_CONNECTION);
        connectionPool = new SFTPConnectionPool(connectionMax, 0);
    }

    private ChannelSftp connect() throws IOException {
        Configuration conf = getConf();

        String host = conf.get(FS_SFTP_HOST, null);
        int port = conf.getInt(FS_SFTP_HOST_PORT, DEFAULT_SFTP_PORT);
        String user = conf.get(FS_SFTP_USER_PREFIX + host, null);
        String pwd = conf.get(FS_SFTP_PASSWORD_PREFIX + host + "." + user, null);
        String keyFile = conf.get(FS_SFTP_KEYFILE, null);

        ChannelSftp channel = connectionPool.connect(host, port, user, pwd, keyFile);

        return channel;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add user info to the URI: sftp://user@host/path
  2. Or set the per-host property: conf.set("fs.sftp.user.<host>", "user") (with fs.sftp.password.<host> as needed)
  3. Provide the credential file that setConfigurationFromURI parses (user:password entries) and ensure its host entry matches the resolved host exactly
  4. Make sure the same host string (hostname vs IP) is used in both URI and config keys

Example fix

// before
URI uri = URI.create("sftp://sftp.example.com/data"); // no user
// after
URI uri = URI.create("sftp://deploy@sftp.example.com/data");
conf.set("fs.sftp.password.sftp.example.com", "secret");
Defensive patterns

Strategy: validation

Validate before calling

String host = uri.getHost();
if (uri.getUserInfo() == null && conf.get("fs.sftp.user." + host) == null)
    throw new IllegalArgumentException("SFTP user missing: set user-info or fs.sftp.user." + host);

Prevention

When it happens

Trigger: URI has no user-info (sftp://host/path) and no fs.sftp.user.<host> (or credential file providing user/password pairs) is configured for the resolved host.

Common situations: Moving jobs between environments where the credential file isn't present; host name mismatch so the FS_SFTP_USER_PREFIX + host key doesn't match the configured key (e.g. IP vs hostname); forgot to set user-info in the URI.

Related errors


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