Java – 530 User cannot login with FTPSClient

ftpjavassl

We're attempting to access one of our FTPS servers using the same credentials as we would in our standard FTP client. However, when using the Java class FTPSClient we are getting the error message:

530 User cannot log in.

And nothing else. So far we have the following code (Simplified for the example):

public final class FTPSExample {

    public static final void main(String[] args) {
        boolean error = false;
        String server, username, password;
        String protocol = "TLS";    // SSL/TLS
        FTPSClient ftps;


        server = "A_SERVER";
        username = /*server + "|" + */"A_USER";
        password = "A_PASS";

        ftps = new FTPSClient(protocol);
        ftps.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());

        ftps.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));

        try {
            int reply;

            ftps.connect(server, 21);
            System.out.println("Connected to " + server + ".");

            reply = ftps.getReplyCode();

            if (!FTPReply.isPositiveCompletion(reply)) {
                ftps.disconnect();
                System.err.println("FTP server refused connection.");
            } else {
                ftps.sendCommand("HOST", server);

                if (!ftps.login(username, password)) {
                    String[] welcomeMessage = ftps.getReplyStrings();
                    for(String s : welcomeMessage) {
                        System.out.println(s);
                    }
                    ftps.logout();
                    error = true;
                }
            }
        }
        catch (IOException e) {
            if (ftps.isConnected()) {
                try {
                    ftps.disconnect();
                }
                catch (IOException f) {
                    // do nothing
                }
            }
            System.err.println("Could not connect to server.");
            e.printStackTrace();
            System.exit(1);
        }
        System.exit(error ? 1 : 0);
    }
}

The above code gives us the following log messages:

220 Microsoft FTP Service
AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
Connected to A_SERVER.
HOST A_SERVER
220 Host accepted.
USER A_USER
331 Password required for A_USER.
PASS A_PASS
530 User cannot log in.
530 User cannot log in.
QUIT
221 Goodbye.

Meanwhile if we do the same in an FTP client (E.g. FTP Voyager) we get:

STATUS:>    Connecting to "A_SERVER" on port 21.
    220 Microsoft FTP Service
COMMAND:>   AUTH TLS
    234 AUTH command ok. Expecting TLS Negotiation.
STATUS:>    Negotiating SSL connection with server.
STATUS:>    SSL connection established.  All transactions are now secure.
STATUS:>    Connected.  Logging into the server
COMMAND:>   HOST A_SERVER
    220 Host accepted.
COMMAND:>   USER A_USER
    331 Password required for A_USER.
COMMAND:>   PASS *********************
    230 User logged in.
STATUS:>    Login successful

Some of the trouble shooting we've tried:

  • Changing the protocol from TLS to SSL, both suffer the same problem
  • Adding the command ftps.sendCommand("HOST", server);. We saw that the FTP client was running this command before logging in, without that line we instead got the error: 530 Valid hostname is expected.
  • Using FTPClient, which results in the expected 534 Policy requires SSL.
  • Removing the ftps.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager()); which results in the same error
  • Instead of setting HOST, using the user as: username = "A_SERVER|A_USER";. Same error message

The server does come with a certificate, which for debugging purposes we are happy to ignore. This is why we set the TrustManager as accepting all. Is there another setting we should be aware of?

We have no proxy set, and we're not getting a helpful error message. Googling for 530 User cannot log in. does not provide anything useful so far. Does anyone have any suggestions?

EDIT

I manage to get it working using a different package called FTP4J, however if anyone could shed any light on why the FTPSClient isn't working, that would be fantastic. Here's the working code:

public final class FTPSExample {

    public static final void main(String[] args) {
        boolean error = false;
        String server, username, password;
        FTPClient ftps;

        server = "A_SERVER";
        username = server + "|" + "A_USER";
        password = "A_PASS";

        ftps = new FTPClient();
        ftps.setSecurity(FTPClient.SECURITY_FTPES);
        ftps.addCommunicationListener(new FTPCommunicationListener() {

            @Override
            public void sent(String s) {
                System.out.println(s);
            }

            @Override
            public void received(String s) {
                System.out.println(s);
            }
        });

        try {

            ftps.connect(server);
            System.out.println("Connected to " + server + ".");

            if (!ftps.isConnected()) {
                ftps.disconnect(false);
                System.err.println("FTP server refused connection.");
            } else {
                //ftps.sendSiteCommand("HOST " + server);

                ftps.login(username, password);

                if (!ftps.isAuthenticated()) {
                    error = true;
                } else {
                    System.out.println("Connected!");
                }
                ftps.logout();
            }
        }
        catch (Exception e) {
            if (ftps.isConnected()) {
                try {
                    ftps.disconnect(false);
                }
                catch (Exception f) {
                    // do nothing
                }
            }
            System.err.println("Could not connect to server.");
            e.printStackTrace();
            System.exit(1);
        }
        System.exit(error ? 1 : 0);
    }
}

And the resulting data:

220 Microsoft FTP Service
Connected to A_SERVER.
AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
USER A_SERVER|A_USER
331 Password required for A_SERVER|A_USER.
PASS A_PASS
230 User logged in.

Best Answer

I remember that when I have tried to change my code from FTP to FTPS I had the same error and I have solved it using this code:

public void FTPSUploader(String host, String user, String pwd,int numPort) throws Exception {
    FTPSClient ftp = new FTPSClient();
    ftps.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
    int reply;
    ftps.connect(host, numPort);
    reply = ftp.getReplyCode();
    if (!FTPReply.isPositiveCompletion(reply)) {
        ftps.disconnect();
        throw new Exception("Exception in connecting to FTPs Server");
    }
    ftps.login(user, pwd);
    ftps.setFileType(FTP.BINARY_FILE_TYPE);
    ftps.enterLocalPassiveMode();
    ftps.execPBSZ(0);// Set protection buffer size
    ftps.execPROT("P");// Set data channel protection to private--
}
Related Topic