Firewall filter hits multiple rules

Dear all,
I have some firewall filter rules to limit login attempts on a FTP server behind the router. The rules are

add action=drop chain=forward comment="drop FTP bruteforcers" dst-port=21 \
    protocol=tcp src-address-list=ftp_blacklist
add action=add-dst-to-address-list address-list=ftp_blacklist \
    address-list-timeout=1w chain=forward comment="FTP bruteforcers to list" \
    content="530 Login incorrect" dst-address-list=ftp_2nd_fail protocol=tcp
add action=add-dst-to-address-list address-list=ftp_2nd_fail \
    address-list-timeout=1w chain=forward content="530 Login incorrect" \
    dst-address-list=ftp_1st_fail protocol=tcp
add action=add-dst-to-address-list address-list=ftp_1st_fail \
    address-list-timeout=1w chain=forward content="530 Login incorrect" \
    protocol=tcp

The rules work as expected in limit the login to 3 attempts, but somehow the packets hits multiple rules.
I mean, when there is a first incorrect login, the destination IP is added to ftp_1st_fail address list, but when the same IP tries another login and fails, this IP is added to ftp_2nd_fail, but also again in ftp_1st_fail, meaning the timeout is set again to 1 week.
How is it that and how, if possible, can i prevent this from happening?
Thank you.

This is how rules works. Going from top to bottom until there are some stopping it.
So it will be added to 1st list even if its already added to 2nd list and with 1 week that will for sure happen.

I do use these rules to block multiple login on ftp over a 2 hour time period.

add action=jump chain=forward comment="Brute Focre against port 21" dst-port=21 in-interface=ether1 jump-target=anti-bruteforce
add action=return chain=anti-bruteforce dst-limit=1/1h,2,src-address/2h
add action=add-src-to-address-list address-list=List_Brute_Force address-list-timeout=1w3d chain=anti-bruteforce

Normal a user starts and FTP session once a while. If some one tries with wrong password, it will try many times and at last be added to the block list and in user will then be blocked for 10 days by a rule in raw

/ip firewall raw
add action=drop chain=prerouting  dst-port=21  in-interface=ether1 protocol=tcp src-address-list=List_Brute_Force

Quick question Jotne,
Do you run many servers?
What would be the difference of simply using a drop all rule at the end of your input chain and forward chain (which would drop all those attempts anyway).
What am I missing?

I know that firewall rules are evaluated top to bottom until a packet hit one of them. According to this, I think that my rules should work like this:

  1. someone tries to connect to the FTP server with an invalid login, the 4th rule is hit and the IP added to ftp_1st_fail
  2. there is a second invalid login attempt from an IP already in ftp_1st_fail, the 3rd rule is hit, the IP is added to ftp_2nd_fail and the process stop

and so on until the IP is added to ftp_blacklist and all subsequent login attempt is blocked.
But I see that a packet that should get caught by 3rd rule is also caught by 4rd rule.
What am I missing?

Just a couple of server. For me this works. I do have other ports in the same rule, not just FTP (21)

It seems that firewall behaviour is as you described, but according to the wiki:

When processing a chain, rules are taken from the chain in the order they are listed there from top to bottom. If a packet matches the criteria of the rule, then the specified action is performed on it, and no more rules are processed in that chain (the exception is the passthrough action).