I' ve had the same issues in the past and it occurs when you' re proxying the FTP control traffic for scanning purposes. The command sent by the client is received by the firewall/proxy in a garbled manner so it discards it as rubbish and it doesn' t get sent to the actual FTP server.
As my understanding goes...
The only way I ever got past this was to disable any form of FTP control traffic proxying/inspection. For FTP over explicit SSL (you declare your desire to encrypt), as the connection is set up, it begins life unencrypted with your username and password, then you send a command that says please encrypt, you get a challenge/certificate, accept it and then your FTP client issues the LIST command, which is encrypted. The firewall/proxy receives a packet on port 21 that means nothing to it and it gets discarded because it' s encrypted.
Given that you' re having this problem, I guess this is the same issue with the Fortigate so ensure that there is no protection profile interfering with the control traffic on port 21 - just pass it as TCP/21 without scanning it. Generally it is only command traffic anyway and doesn' t contain data, that' s what your passive range is for.
HTH.
As I said, this is my interpretation of the issue since I had to resolve the issue for clients connecting to our FTP explicit SSL server. They were proxying/scanning the FTP traffic which worked fine when unencrypted but fell over as soon as it was encrypted. Simply using a standard unencrypted TCP port instead of a proxied/scannable port resolved the issue for them.