diff --git a/src/main/java/it/inaf/oats/vospace/FileServiceClient.java b/src/main/java/it/inaf/oats/vospace/FileServiceClient.java
index f17719eafe7923c02b8e591d87b496cae92d27d8..a976e921463f9705737e3daf966af811b50418a5 100644
--- a/src/main/java/it/inaf/oats/vospace/FileServiceClient.java
+++ b/src/main/java/it/inaf/oats/vospace/FileServiceClient.java
@@ -7,14 +7,19 @@ package it.inaf.oats.vospace;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import it.inaf.ia2.aa.data.User;
+import it.inaf.oats.vospace.datamodel.NodeUtils;
 import it.inaf.oats.vospace.datamodel.Views;
 import it.inaf.oats.vospace.exception.InvalidArgumentException;
+import it.inaf.oats.vospace.exception.NodeNotFoundException;
 import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
+import it.inaf.oats.vospace.persistence.NodeDAO;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 import javax.servlet.http.HttpServletRequest;
+import net.ivoa.xml.vospace.v2.ContainerNode;
+import net.ivoa.xml.vospace.v2.Node;
 import net.ivoa.xml.vospace.v2.Transfer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -41,10 +46,13 @@ public class FileServiceClient {
 
     @Autowired
     private HttpServletRequest request;
-    
+
     @Autowired
     private LinkService linkService;
 
+    @Autowired
+    private NodeDAO nodeDAO;
+
     public String startArchiveJob(Transfer transfer, String jobId) {
 
         String target = transfer.getTarget().substring("vos://".length() + authority.length());
@@ -69,11 +77,33 @@ public class FileServiceClient {
             // Add target path
             vosPaths.add(target);
         }
-        
-        // OK generate descriptors
-        
+
+        // Generate descriptors
+        // Expand container nodes into direct children list
+        List<String> expandedVosPaths = new ArrayList<>();
+
+        for (String vosPath : vosPaths) {
+            Node node
+                    = nodeDAO.listNode(vosPath)
+                            .orElseThrow(() -> {
+                                throw new NodeNotFoundException(vosPath);
+                            });
+
+            if (node instanceof ContainerNode) {
+                List<Node> nodes = ((ContainerNode) node).getNodes();
+                if (nodes.isEmpty()) {
+                    expandedVosPaths.add(NodeUtils.getVosPath(node));
+                } else {
+                    expandedVosPaths.addAll(nodes
+                            .stream().map(n -> NodeUtils.getVosPath(n))
+                            .collect(Collectors.toList()));
+                }
+            }
+
+        }
+
         // follow links to links in vosPaths
-        List<ArchiveEntryDescriptor> entryDescriptors = linkService.followLinksForArchiveService(vosPaths);
+        List<ArchiveEntryDescriptor> entryDescriptors = linkService.followLinksForArchiveService(expandedVosPaths);
 
         ArchiveRequest archiveRequest = new ArchiveRequest();
         archiveRequest.setJobId(jobId);
@@ -97,17 +127,17 @@ public class FileServiceClient {
             return res.getHeaders().getLocation().toString();
         }, new Object[]{});
     }
-    
-    public void startFileCopyJob(String sourceVosPath, 
+
+    public void startFileCopyJob(String sourceVosPath,
             String destiantionVosPath, String jobId, User user) {
-        
+
         CopyRequest copyRequest = new CopyRequest();
         copyRequest.setJobId(jobId);
         copyRequest.setSourceRootVosPath(sourceVosPath);
         copyRequest.setDestinationRootVosPath(destiantionVosPath);
-        
+
         String url = fileServiceUrl + "/copy";
-        
+
         String token = user.getAccessToken();
         restTemplate.execute(url, HttpMethod.POST, req -> {
             HttpHeaders headers = req.getHeaders();
@@ -119,12 +149,12 @@ public class FileServiceClient {
             try (OutputStream os = req.getBody()) {
                 MAPPER.writeValue(os, copyRequest);
             }
-        }, res -> {           
-           return null;
+        }, res -> {
+            return null;
         }, new Object[]{});
-        
+
     }
-    
+
     public static class CopyRequest {
 
         private String jobId;
@@ -161,7 +191,7 @@ public class FileServiceClient {
 
         private String type;
         private String jobId;
-        private List<ArchiveEntryDescriptor> entryDescriptors;        
+        private List<ArchiveEntryDescriptor> entryDescriptors;
 
         public String getType() {
             return type;
diff --git a/src/main/java/it/inaf/oats/vospace/LinkService.java b/src/main/java/it/inaf/oats/vospace/LinkService.java
index 06530cb45b8c875cc3a431efd0690f45b6769eb1..729c643a34a5d83eefc9b5972fbe6b76b9455760 100644
--- a/src/main/java/it/inaf/oats/vospace/LinkService.java
+++ b/src/main/java/it/inaf/oats/vospace/LinkService.java
@@ -67,7 +67,7 @@ public class LinkService {
     }
     
     private ArchiveEntryDescriptor getLinkNodeArchiveEntryDescriptor(LinkNode node){
-        String vosPath = NodeUtils.getVosPath(node);
+        String vosPath = NodeUtils.getVosPath(node);        
         String targetNodeVosPath = NodeUtils.getVosPath(this.followLink(node));
         
         return new ArchiveEntryDescriptor(vosPath, targetNodeVosPath);
diff --git a/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java b/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java
index 0ed704218f9b3d8a161f59fea50f45da648c039d..9ec78b9fb679cb4250975eb692873f656978d8e2 100644
--- a/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java
+++ b/src/test/java/it/inaf/oats/vospace/FileServiceClientTest.java
@@ -11,12 +11,16 @@ import it.inaf.oats.vospace.FileServiceClient.ArchiveRequest;
 import it.inaf.oats.vospace.datamodel.Views;
 import it.inaf.oats.vospace.exception.InvalidArgumentException;
 import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
+import it.inaf.oats.vospace.persistence.NodeDAO;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.net.URI;
 import java.util.List;
+import java.util.Optional;
 import javax.servlet.http.HttpServletRequest;
+import net.ivoa.xml.vospace.v2.ContainerNode;
+import net.ivoa.xml.vospace.v2.DataNode;
 import net.ivoa.xml.vospace.v2.Param;
 import net.ivoa.xml.vospace.v2.Transfer;
 import net.ivoa.xml.vospace.v2.View;
@@ -30,6 +34,7 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -59,6 +64,9 @@ public class FileServiceClientTest {
     
     @Mock
     private LinkService linkService;
+    
+    @Mock
+    private NodeDAO nodeDAO;
 
     @InjectMocks
     private FileServiceClient fileServiceClient;
@@ -98,6 +106,11 @@ public class FileServiceClientTest {
         view.setUri(Views.ZIP_VIEW_URI);
         transfer.setView(view);
         
+        ContainerNode node = Mockito.mock(ContainerNode.class);
+        when(node.getNodes()).thenReturn(List.of());
+        when(node.getUri()).thenReturn("vos://example.com!vospace/mydir");
+        when(nodeDAO.listNode(eq("/mydir"))).thenReturn(Optional.of(node));
+        
         when(linkService.followLinksForArchiveService(any()))
                 .thenReturn(List.of(new ArchiveEntryDescriptor("/mydir")));
 
@@ -162,6 +175,14 @@ public class FileServiceClientTest {
         param2.setValue("file2");
         view.getParam().add(param2);
         
+        DataNode node1 = Mockito.mock(DataNode.class);
+        when(node1.getUri()).thenReturn("vos://example.com!vospace/parent_dir/file1");
+        when(nodeDAO.listNode(eq("/parent_dir/file1"))).thenReturn(Optional.of(node1));
+        
+        DataNode node2 = Mockito.mock(DataNode.class);
+        when(node2.getUri()).thenReturn("vos://example.com!vospace/parent_dir/file2");
+        when(nodeDAO.listNode(eq("/parent_dir/file2"))).thenReturn(Optional.of(node2));
+        
         when(linkService.followLinksForArchiveService(any())).thenReturn(
                 List.of(new ArchiveEntryDescriptor("/parent_dir/file1"),
                         new ArchiveEntryDescriptor("/parent_dir/file2")                
diff --git a/src/test/java/it/inaf/oats/vospace/LinkServiceTest.java b/src/test/java/it/inaf/oats/vospace/LinkServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..091e4d0ccd7348c8c494a3b6ec0e0646134025f6
--- /dev/null
+++ b/src/test/java/it/inaf/oats/vospace/LinkServiceTest.java
@@ -0,0 +1,61 @@
+/*
+ * This file is part of vospace-rest
+ * Copyright (C) 2021 Istituto Nazionale di Astrofisica
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+package it.inaf.oats.vospace;
+
+import it.inaf.ia2.aa.data.User;
+import it.inaf.oats.vospace.exception.NodeBusyException;
+import it.inaf.oats.vospace.exception.NodeNotFoundException;
+import it.inaf.oats.vospace.exception.PermissionDeniedException;
+import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
+import it.inaf.oats.vospace.persistence.DataSourceConfigSingleton;
+import it.inaf.oats.vospace.persistence.NodeDAO;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import net.ivoa.xml.vospace.v2.Transfer;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.ContextConfiguration;
+
+@SpringBootTest
+//@AutoConfigureMockMvc
+@TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"})
+@ContextConfiguration(classes = {DataSourceConfigSingleton.class})
+public class LinkServiceTest {
+
+    @Autowired
+    private LinkService linkService;
+    
+    @Test
+    public void testFollowLinksForArchiveService() {
+        List<String> vosPaths = List.of("/test3/m1/link2", "/test3/m1/m2");
+        
+        List<ArchiveEntryDescriptor> aed = linkService.followLinksForArchiveService(vosPaths);
+        
+        assertEquals(2, aed.size());
+        List<String> targetVosPaths = aed.stream().map(a -> a.getTargetNodeVosPath())
+                .collect(Collectors.toList());
+        
+        System.out.println(targetVosPaths);        
+        assertTrue(targetVosPaths.containsAll(List.of("/test3/m1/m2", "/test1/f1/f2_renamed/f3")));
+                
+    }
+
+    
+}
diff --git a/src/test/resources/test-data.sql b/src/test/resources/test-data.sql
index 7827a3af033234d0933bc14a43b5393a98ce348f..b9e8f6d18bb59a785e9e6dd52c923bfda64f70e2 100644
--- a/src/test/resources/test-data.sql
+++ b/src/test/resources/test-data.sql
@@ -43,6 +43,7 @@ INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, gro
 INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id) VALUES ('19', '', 'destination2', 'container', 'user3', '{"group1"}', '{"group1"}', false, 3);      -- /mycontainer/destination2
 INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id) VALUES ('19.21', '20', 'control', 'container', 'user3', '{"group1"}', '{"group1"}', false, 3);      -- /mycontainer/destination2/control
 
+INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id, target) VALUES ('9.10', '', 'link2', 'link', 'user3', '{"group1"}', '{"group1"}', false, 3, 'vos://example.com!vospace/test1/f1/f2_renamed/f3');      -- /test3/m1/link2
 
 DELETE FROM job;