diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSDepthException.java b/src/main/java/org/olat/core/util/vfs/restapi/VFSDepthException.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7271f79e4862c677a41cc569df2a99cf2846f08
--- /dev/null
+++ b/src/main/java/org/olat/core/util/vfs/restapi/VFSDepthException.java
@@ -0,0 +1,37 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.util.vfs.restapi;
+
+import java.io.IOException;
+
+/**
+ * 
+ * 
+ * Initial date: 6 juin 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class VFSDepthException extends IOException {
+
+	private static final long serialVersionUID = 7550064282144460698L;
+	
+	
+
+}
diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java b/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java
index 7debe5390c91fd8001a5f87f8c4ff4a62da0eca9..d5fc18116890f5d4f83a011f5eae0d262ee675fb 100644
--- a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java
+++ b/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java
@@ -74,8 +74,9 @@ public class VFSWebservice {
 	private static final String VERSION  = "1.0";
 	
 	private static final OLog log = Tracing.createLoggerFor(VFSWebservice.class);
+	private static final int MAX_FOLDER_DEPTH = 20;
 	
-	public static CacheControl cc = new CacheControl();
+	private static final CacheControl cc = new CacheControl();
 	static {
 		cc.setMaxAge(-1);
 	}
@@ -182,8 +183,13 @@ public class VFSWebservice {
 	public Response postFile64ToRoot(@FormParam("foldername") String foldername, @FormParam("filename") String filename,
 			@FormParam("file") String file, @Context UriInfo uriInfo) {
 		byte[] fileAsBytes = Base64.decodeBase64(file);
-		InputStream in = new ByteArrayInputStream(fileAsBytes);
-		return putFile(foldername, filename, in, uriInfo, Collections.<PathSegment>emptyList());
+		try(InputStream in = new ByteArrayInputStream(fileAsBytes)) {
+			return putFile(foldername, filename, in, uriInfo, Collections.<PathSegment>emptyList());
+		} catch (VFSDepthException e) {
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
+		} catch (IOException e) {
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
 	}
 	
 	/**
@@ -224,8 +230,13 @@ public class VFSWebservice {
 	public Response postFile64ToFolder(@FormParam("foldername") String foldername, @FormParam("filename") String filename,
 			@FormParam("file") String file, @Context UriInfo uriInfo, @PathParam("path") List<PathSegment> path) {
 		byte[] fileAsBytes = Base64.decodeBase64(file);
-		InputStream in = new ByteArrayInputStream(fileAsBytes);
-		return putFile(foldername, filename, in, uriInfo, path);
+		try(InputStream in = new ByteArrayInputStream(fileAsBytes)) {
+			return putFile(foldername, filename, in, uriInfo, path);
+		} catch (VFSDepthException e) {
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
+		} catch (IOException e) {
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
 	}
 	
 	/**
@@ -260,8 +271,13 @@ public class VFSWebservice {
 	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
 	public Response putFile64VOToRoot(File64VO file, @Context UriInfo uriInfo) {
 		byte[] fileAsBytes = Base64.decodeBase64(file.getFile());
-		InputStream in = new ByteArrayInputStream(fileAsBytes);
-		return putFile(null, file.getFilename(), in, uriInfo, Collections.<PathSegment>emptyList());
+		try(InputStream in = new ByteArrayInputStream(fileAsBytes)) {
+			return putFile(null, file.getFilename(), in, uriInfo, Collections.<PathSegment>emptyList());
+		} catch (VFSDepthException e) {
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
+		} catch (IOException e) {
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
 	}
 	
 	/**
@@ -300,6 +316,9 @@ public class VFSWebservice {
 		} catch (FileNotFoundException e) {
 			log.error("", e);
 			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}  catch (VFSDepthException e) {
+			log.error("", e);
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
 		} finally {
 			MultipartReader.closeQuietly(partsReader);
 			IOUtils.closeQuietly(in);
@@ -323,8 +342,13 @@ public class VFSWebservice {
 	@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
 	public Response putFile64ToFolder(File64VO file, @Context UriInfo uriInfo, @PathParam("path") List<PathSegment> path) {
 		byte[] fileAsBytes = Base64.decodeBase64(file.getFile());
-		InputStream in = new ByteArrayInputStream(fileAsBytes);
-		return putFile(null, file.getFilename(), in, uriInfo, path);
+		try(InputStream in = new ByteArrayInputStream(fileAsBytes)) {
+			return putFile(null, file.getFilename(), in, uriInfo, path);
+		} catch (VFSDepthException e) {
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
+		} catch(IOException e) {
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
 	}
 	
 	/**
@@ -368,15 +392,23 @@ public class VFSWebservice {
 		if(container.getLocalSecurityCallback() != null && !container.getLocalSecurityCallback().canWrite()) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
+		if(path.size() >= MAX_FOLDER_DEPTH) {
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
+		}
 		
-		VFSContainer directory = resolveContainer(path, true);
-		if(directory == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
+		try {
+			VFSContainer directory = resolveContainer(path, true);
+			if(directory == null) {
+				return Response.serverError().status(Status.NOT_FOUND).build();
+			}
+			return Response.ok(createFileVO(directory, uriInfo)).build();
+		} catch (VFSDepthException e) {
+			return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
 		}
-		return Response.ok(createFileVO(directory, uriInfo)).build();
 	}
 	
-	protected Response putFile(String foldername, String filename, InputStream file, UriInfo uriInfo, List<PathSegment> path) {
+	private Response putFile(String foldername, String filename, InputStream file, UriInfo uriInfo, List<PathSegment> path)
+	throws VFSDepthException {
 		if(container.getLocalSecurityCallback() != null && !container.getLocalSecurityCallback().canWrite()) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
@@ -476,15 +508,19 @@ public class VFSWebservice {
 		return Response.serverError().status(Status.BAD_REQUEST).build();
 	}
 	
-	protected VFSContainer resolveContainer(List<PathSegment> path, boolean create) {
+	protected VFSContainer resolveContainer(List<PathSegment> path, boolean create) throws VFSDepthException {
 		VFSContainer directory = container;
 		boolean notFound = false;
 		
 		//remove trailing segment if a trailing / is used
-		if(path.size() > 0 && !StringHelper.containsNonWhitespace(path.get(path.size() - 1).getPath())) {
+		if(!path.isEmpty() && !StringHelper.containsNonWhitespace(path.get(path.size() - 1).getPath())) {
 			path = path.subList(0, path.size() -1);
 		}
 		
+		if(create && path.size() >= MAX_FOLDER_DEPTH) {
+			throw new VFSDepthException();
+		}
+		
 		a_a:
 		for(PathSegment seg:path) {
 			String segPath = seg.getPath();
@@ -517,7 +553,7 @@ public class VFSWebservice {
 		boolean notFound = false;
 		
 		//remove trailing segment if a trailing / is used
-		if(path.size() > 0 && !StringHelper.containsNonWhitespace(path.get(path.size() - 1).getPath())) {
+		if(!path.isEmpty() && !StringHelper.containsNonWhitespace(path.get(path.size() - 1).getPath())) {
 			path = path.subList(0, path.size() -1);
 		}
 		
diff --git a/src/test/java/org/olat/restapi/CoursesFoldersTest.java b/src/test/java/org/olat/restapi/CoursesFoldersTest.java
index 7a17016f1b894dda53312660b7351b34a1f8425e..53b06f5ad4279eab5ad3adb73a0431a6648a37f1 100644
--- a/src/test/java/org/olat/restapi/CoursesFoldersTest.java
+++ b/src/test/java/org/olat/restapi/CoursesFoldersTest.java
@@ -219,6 +219,20 @@ public class CoursesFoldersTest extends OlatJerseyTestCase {
 		assertTrue(item2 instanceof VFSContainer);
 	}
 	
+	@Test
+	public void testCreateFolders_tooMany() throws IOException, URISyntaxException {
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		URI uri = UriBuilder.fromUri(getNodeURI()).path("files").path("RootFolder")
+				.path("Folder").path("Folder").path("Folder").path("Folder").path("Folder")
+				.path("Folder").path("Folder").path("Folder").path("Folder").path("Folder")
+				.path("Folder").path("Folder").path("Folder").path("Folder").path("Folder")
+				.path("Folder").path("Folder").path("Folder").path("Folder").path("Folder").build();
+		HttpPut method = conn.createPut(uri, MediaType.APPLICATION_JSON, true);
+		HttpResponse response = conn.execute(method);
+		assertEquals(406, response.getStatusLine().getStatusCode());
+	}
+	
 	@Test
 	public void deleteFolder() throws IOException, URISyntaxException {
 		//add some folders