if (mlx5e_is_eswitch_flow(parse_state->flow))
                attr->esw_attr->split_count = attr->esw_attr->out_count;
 
-       if (!clear_action) {
+       if (clear_action) {
+               parse_state->ct_clear = true;
+       } else {
                attr->flags |= MLX5_ATTR_FLAG_CT;
                flow_flag_set(parse_state->flow, CT);
                parse_state->ct = true;
        }
-       parse_state->ct_clear = clear_action;
+
+       return 0;
+}
+
+static int
+tc_act_post_parse_ct(struct mlx5e_tc_act_parse_state *parse_state,
+                    struct mlx5e_priv *priv,
+                    struct mlx5_flow_attr *attr)
+{
+       struct mlx5e_tc_mod_hdr_acts *mod_acts = &attr->parse_attr->mod_hdr_acts;
+       int err;
+
+       /* If ct action exist, we can ignore previous ct_clear actions */
+       if (parse_state->ct)
+               return 0;
+
+       if (parse_state->ct_clear) {
+               err = mlx5_tc_ct_set_ct_clear_regs(parse_state->ct_priv, mod_acts);
+               if (err) {
+                       NL_SET_ERR_MSG_MOD(parse_state->extack,
+                                          "Failed to set registers for ct clear");
+                       return err;
+               }
+               attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+
+               /* Prevent handling of additional, redundant clear actions */
+               parse_state->ct_clear = false;
+       }
 
        return 0;
 }
        .can_offload = tc_act_can_offload_ct,
        .parse_action = tc_act_parse_ct,
        .is_multi_table_act = tc_act_is_multi_table_act_ct,
+       .post_parse = tc_act_post_parse_ct,
 };
 
 
        return 0;
 }
 
+int mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
+                                struct mlx5e_tc_mod_hdr_acts *mod_acts)
+{
+               return mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0);
+}
+
 static int
 mlx5_tc_ct_parse_mangle_to_mod_act(struct flow_action_entry *act,
                                   char *modact)
                        const struct flow_action_entry *act,
                        struct netlink_ext_ack *extack)
 {
-       bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR;
-       int err;
-
        if (!priv) {
                NL_SET_ERR_MSG_MOD(extack,
                                   "offload of ct action isn't available");
        attr->ct_attr.ct_action = act->ct.action;
        attr->ct_attr.nf_ft = act->ct.flow_table;
 
-       if (!clear_action)
-               goto out;
-
-       err = mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0);
-       if (err) {
-               NL_SET_ERR_MSG_MOD(extack, "Failed to set registers for ct clear");
-               return err;
-       }
-       attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
-
-out:
        return 0;
 }
 
 
 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
                         struct sk_buff *skb, u8 zone_restore_id);
 
+int
+mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
+                            struct mlx5e_tc_mod_hdr_acts *mod_acts);
+
 #else /* CONFIG_MLX5_TC_CT */
 
 static inline struct mlx5_tc_ct_priv *
        return 0;
 }
 
+static inline int
+mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
+                            struct mlx5e_tc_mod_hdr_acts *mod_acts)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int
 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
                        struct mlx5_flow_attr *attr,