diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java
index d4d423da408075ed1d1b9d6efdcd538056c419aa..6ec471c0ffca140e3c6b6f5349d6102ca12949df 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java
@@ -143,7 +143,7 @@ public class DSSFileSystemView implements FileSystemView
             FtpPathResolverContext context =
                     new FtpPathResolverContext(sessionToken, service, generalInfoService,
                             pathResolverRegistry);
-            return pathResolverRegistry.tryResolve(normalizedPath, context);
+            return pathResolverRegistry.resolve(normalizedPath, context);
         } catch (RuntimeException rex)
         {
             String message =
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpPathResolverRegistry.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpPathResolverRegistry.java
index 31b862e0fd498df745b90faf8b9bceaf454de57e..cee9ed0f854e7c1e3d39cf5936e859b5e72464b4 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpPathResolverRegistry.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpPathResolverRegistry.java
@@ -16,9 +16,14 @@
 
 package ch.systemsx.cisd.openbis.dss.generic.server.ftp;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
+import org.apache.commons.io.FilenameUtils;
 import org.apache.ftpserver.ftplet.FtpFile;
 import org.apache.log4j.Logger;
 
@@ -72,7 +77,7 @@ public class FtpPathResolverRegistry implements IFtpPathResolverRegistry
         return null;
     }
 
-    public FtpFile tryResolve(String path, FtpPathResolverContext resolverContext)
+    public FtpFile resolve(String path, FtpPathResolverContext resolverContext)
     {
         IFtpPathResolver resolver = tryFindResolver(path);
         if (resolver != null)
@@ -83,8 +88,137 @@ public class FtpPathResolverRegistry implements IFtpPathResolverRegistry
             String message =
                     String.format("Cannot find resolver for path '%s'. Wrong user input ?", path);
             operationLog.warn(message);
-            return null;
+            return getNonExistingFile(path, message);
         }
     }
 
+    /**
+     * Create a representation for a non-existing {@link FtpFile}, optionally providing an error
+     * message.
+     */
+    public static final FtpFile getNonExistingFile(final String path, final String errorMsgOrNull)
+    {
+        return new FtpFile()
+            {
+                public String getAbsolutePath()
+                {
+                    return path;
+                }
+    
+                public String getName()
+                {
+                    return FilenameUtils.getName(path);
+                }
+    
+                public boolean isHidden()
+                {
+                    return false;
+                }
+    
+                public boolean isDirectory()
+                {
+                    return false;
+                }
+    
+                public boolean isFile()
+                {
+                    return false;
+                }
+    
+                public boolean doesExist()
+                {
+                    return false;
+                }
+    
+                public boolean isReadable()
+                {
+                    return false;
+                }
+    
+                public boolean isWritable()
+                {
+                    return false;
+                }
+    
+                public boolean isRemovable()
+                {
+                    return false;
+                }
+    
+                public String getOwnerName()
+                {
+                    return "UNKNOWN";
+                }
+    
+                public String getGroupName()
+                {
+                    return "UNKNOWN";
+                }
+    
+                public int getLinkCount()
+                {
+                    return 0;
+                }
+    
+                public long getLastModified()
+                {
+                    return 0;
+                }
+    
+                public boolean setLastModified(long time)
+                {
+                    return false;
+                }
+    
+                public long getSize()
+                {
+                    return 0;
+                }
+    
+                public boolean mkdir()
+                {
+                    return false;
+                }
+    
+                public boolean delete()
+                {
+                    return false;
+                }
+    
+                public boolean move(FtpFile destination)
+                {
+                    return false;
+                }
+    
+                public List<FtpFile> listFiles()
+                {
+                    return Collections.emptyList();
+                }
+    
+                public OutputStream createOutputStream(long offset) throws IOException
+                {
+                    if (errorMsgOrNull != null)
+                    {
+                        throw new IOException("File '" + path + "' does not exist ("
+                                + errorMsgOrNull + ".");
+                    } else
+                    {
+                        throw new IOException("File '" + path + "' does not exist.");
+                    }
+                }
+    
+                public InputStream createInputStream(long offset) throws IOException
+                {
+                    if (errorMsgOrNull != null)
+                    {
+                        throw new IOException("File '" + path + "' does not exist ("
+                                + errorMsgOrNull + ".");
+                    } else
+                    {
+                        throw new IOException("File '" + path + "' does not exist.");
+                    }
+                }
+            };
+    }
+
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/IFtpPathResolverRegistry.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/IFtpPathResolverRegistry.java
index ab79a831eeb77964fc143a2033b2d8d55d7f9956..35ecfca203ff3778174f1682bc3c6273b57a1c0a 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/IFtpPathResolverRegistry.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/IFtpPathResolverRegistry.java
@@ -24,6 +24,11 @@ import org.apache.ftpserver.ftplet.FtpFile;
 public interface IFtpPathResolverRegistry
 {
 
-    FtpFile tryResolve(String path, FtpPathResolverContext resolverContext);
+    /**
+     * Returns an {@link FtpFile} for <var>path</var>.
+     * <p>
+     * <i>You need to check {@link FtpFile#doesExist()} before using it!</i>
+     */
+    FtpFile resolve(String path, FtpPathResolverContext resolverContext);
 
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/ProjectFolderResolver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/ProjectFolderResolver.java
index fef581f8a4b4a5e5e2b639daf09c20786916c460..89e5903264c5a952443c8b04f3d6429e432c294e 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/ProjectFolderResolver.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/ProjectFolderResolver.java
@@ -63,7 +63,7 @@ public class ProjectFolderResolver implements IFtpPathResolver
                         String childPath =
                                 path + FtpConstants.FILE_SEPARATOR + experiment.getCode();
                         FtpFile childFile =
-                                resolverContext.getResolverRegistry().tryResolve(childPath,
+                                resolverContext.getResolverRegistry().resolve(childPath,
                                         resolverContext);
                         result.add(childFile);
                     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/RootFolderResolver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/RootFolderResolver.java
index ab8597ebe75f29f599afa040ce54e07c866b70fd..c4140e267b26f2cdb5924967a5b491268ce27931 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/RootFolderResolver.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/RootFolderResolver.java
@@ -64,7 +64,7 @@ public class RootFolderResolver implements IFtpPathResolver
                     {
                         String childPath = FtpConstants.ROOT_DIRECTORY + spaceCode;
                         FtpFile child =
-                                resolverContext.getResolverRegistry().tryResolve(childPath,
+                                resolverContext.getResolverRegistry().resolve(childPath,
                                         resolverContext);
                         if (child != null)
                         {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/SpaceFolderResolver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/SpaceFolderResolver.java
index 599d28dfcf798ce394a59f905bf0c6cd821a6888..d143eb18023900c7def7f6f63e17f60430e85e93 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/SpaceFolderResolver.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/SpaceFolderResolver.java
@@ -70,7 +70,7 @@ public class SpaceFolderResolver implements IFtpPathResolver
                     {
                         String childPath = path + FtpConstants.FILE_SEPARATOR + childProject;
                         FtpFile childFile =
-                                resolverContext.getResolverRegistry().tryResolve(childPath,
+                                resolverContext.getResolverRegistry().resolve(childPath,
                                         resolverContext);
                         result.add(childFile);
                     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java
index 38d880cbf0b82c11780f50652a332ebede61bd8a..280f123407ca4f5f0af2d6b80295dd959ec71ac0 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java
@@ -42,6 +42,7 @@ import ch.systemsx.cisd.common.utilities.Template;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpConstants;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpFileFactory;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpPathResolverContext;
+import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpPathResolverRegistry;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpServerConfig;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.IFtpPathResolver;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.resolver.FtpFileEvaluationContext.EvaluatedElement;
@@ -58,9 +59,11 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi
 
 /**
  * Resolves paths like
+ * 
  * <pre>
  *  /&lt;space-code>/&lt;project-code>/&lt;experiment-code>/&lt;dataset-template>[/[PARENT-&lt;dataset-template>|CHILD-&lt;dataset-template>|&lt;sub-path>]]*
  * </pre>
+ * 
  * to {@link FtpFile} objects.
  * <p>
  * Subpaths are resolved as relative paths starting from the root of a dataset.
@@ -84,12 +87,12 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
     private static final String DATA_SET_DATE_FORMAT = "yyyy-MM-dd-HH-mm";
 
     private static final String PARENT_PREFIX = "PARENT-";
-    
+
     private static final String CHILD_PREFIX = "CHILD-";
-    
+
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
             TemplateBasedDataSetResourceResolver.class);
-    
+
     private final class DataSetFtpFolder extends AbstractFtpFolder
     {
         private final ExternalData dataSet;
@@ -209,7 +212,7 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
     private boolean fileNamePresent;
 
     private IHierarchicalContentProvider contentProvider;
-    
+
     public TemplateBasedDataSetResourceResolver(FtpServerConfig ftpServerConfig)
     {
         this.template = new Template(ftpServerConfig.getDataSetDisplayTemplate());
@@ -217,14 +220,13 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
         fileNamePresent = template.getPlaceholderNames().contains(FILE_NAME_VARNAME);
         if (fileNamePresent && showParentsAndChildren)
         {
-            throw new ConfigurationFailureException(
-                    "Template contains file name variable and "
-                            + "the flag to show parents/children data sets is set.");
+            throw new ConfigurationFailureException("Template contains file name variable and "
+                    + "the flag to show parents/children data sets is set.");
         }
         this.dataSetTypeConfigs = initializeDataSetTypeConfigs(ftpServerConfig);
         this.defaultDSTypeConfig = new DataSetTypeConfig();
     }
-    
+
     void setContentProvider(IHierarchicalContentProvider contentProvider)
     {
         this.contentProvider = contentProvider;
@@ -248,14 +250,15 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
         Experiment experiment = tryGetExperiment(experimentId, service, sessionToken);
         if (experiment == null)
         {
-            throw new IllegalArgumentException("Unknown experiment '" + experimentId + "'.");
+            return FtpPathResolverRegistry.getNonExistingFile(path, "Unknown experiment '"
+                    + experimentId + "'.");
         }
         List<ExternalData> dataSets =
                 service.listDataSetsByExperimentID(sessionToken, new TechId(experiment));
         if (fileNamePresent)
         {
             FtpFileEvaluationContext evalContext = evaluateDataSetPaths(dataSets);
-            
+
             try
             {
                 return extractMatchingFileOrNull(path, experimentId, evalContext);
@@ -282,7 +285,8 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
                 ExternalData dataSet = tryToFindDataSet(dataSets, dataSetPathElement);
                 if (dataSet == null)
                 {
-                    throw createException(dataSetPathElement);
+                    return FtpPathResolverRegistry.getNonExistingFile(path,
+                            "No match found for path element '" + dataSetPathElement + "'.");
                 }
                 String subPath =
                         StringUtils.join(pathElements, FtpConstants.FILE_SEPARATOR, 0, i + 1);
@@ -301,7 +305,8 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
                 }
                 if (matchingFile == null)
                 {
-                    throw createException(dataSetPathElement);
+                    return FtpPathResolverRegistry.getNonExistingFile(path,
+                            "No match found for path element '" + dataSetPathElement + "'.");
                 }
                 result = matchingFile;
             }
@@ -309,12 +314,6 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
         return result;
     }
 
-    private IllegalArgumentException createException(String dataSetPathElement)
-    {
-        return new IllegalArgumentException("No match found for path element '"
-                + dataSetPathElement + "'.");
-    }
-
     private ExternalData tryToFindDataSet(List<ExternalData> dataSets, String dataSetPathElement)
     {
         for (int disambiguationIdx = 0; disambiguationIdx < dataSets.size(); disambiguationIdx++)
@@ -464,8 +463,7 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
                 String childPath =
                         parentPath + FtpConstants.FILE_SEPARATOR + evalElement.evaluatedTemplate;
                 String dataSetCode = evalElement.dataSet.getCode();
-                IHierarchicalContentProvider getContentProvider =
-                        getContentProvider();
+                IHierarchicalContentProvider getContentProvider = getContentProvider();
 
                 FtpFile childFtpFile =
                         FtpFileFactory.createFtpFile(dataSetCode, childPath,
@@ -572,7 +570,8 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
     /**
      * @return all values to be used when evaluating the template "${fileName}" variable.
      */
-    private List<IHierarchicalContentNode> getFileNamesRequiredByTemplate(IHierarchicalContentNode rootNode)
+    private List<IHierarchicalContentNode> getFileNamesRequiredByTemplate(
+            IHierarchicalContentNode rootNode)
     {
         if (fileNamePresent)
         {
@@ -603,7 +602,8 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
     /**
      * Formats a date as it will appear after template evaluation.
      */
-    @Private static String extractDateValue(Date dataSetDate)
+    @Private
+    static String extractDateValue(Date dataSetDate)
     {
         return DateFormatUtils.format(dataSetDate, DATA_SET_DATE_FORMAT);
     }
@@ -692,5 +692,5 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
         }
         return contentProvider;
     }
-    
+
 }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemViewTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemViewTest.java
index c2e23d5bd37dc23ac3a2961a20d1734fc6e095df..17d368af1d1e954cea2baa48383df1aa76c51de0 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemViewTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemViewTest.java
@@ -110,7 +110,7 @@ public class DSSFileSystemViewTest extends AssertJUnit
             {
                 {
                     RecordingMatcher<FtpPathResolverContext> recorder = new RecordingMatcher<FtpPathResolverContext>();
-                    one(registry).tryResolve(with(normalizedPath), with(recorder));
+                    one(registry).resolve(with(normalizedPath), with(recorder));
                     will(returnValue(new AbstractFtpFile(normalizedPath)
                         {