diff --git a/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/DefaultNuxeoExceptionHandler.java b/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/DefaultNuxeoExceptionHandler.java
--- a/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/DefaultNuxeoExceptionHandler.java
+++ b/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/DefaultNuxeoExceptionHandler.java
@@ -21,6 +21,7 @@
 import java.io.StringWriter;
 import java.util.Locale;
 
+import javax.faces.context.FacesContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -31,6 +32,7 @@
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.ClientRuntimeException;
 import org.nuxeo.ecm.core.api.WrappedException;
+import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants;
 import org.nuxeo.ecm.platform.web.common.exceptionhandling.descriptor.ErrorHandler;
 
 /**
@@ -53,48 +55,65 @@
     public void handleException(HttpServletRequest request,
             HttpServletResponse response, Throwable t) throws IOException,
             ServletException {
+        // mark request as already processed by this mechanism to avoid looping
+        // over it
         request.setAttribute(NuxeoExceptionFilter.EXCEPTION_FILTER_ATTRIBUTE,
                 true);
-        ErrorHandler handler = getHandler(t);
-        parameters.getListener().startHandling(t, request, response);
+        // disable further redirect by nuxeo url system
+        request.setAttribute(NXAuthConstants.DISABLE_REDIRECT_REQUEST_KEY, true);
+        try {
+            ErrorHandler handler = getHandler(t);
+            parameters.getListener().startHandling(t, request, response);
 
-        Throwable unwrappedException = unwrapException(t);
-        StringWriter swriter = new StringWriter();
-        PrintWriter pwriter = new PrintWriter(swriter);
-        t.printStackTrace(pwriter);
-        String stackTrace = swriter.getBuffer().toString();
-        log.error(stackTrace);
-        parameters.getLogger().error(stackTrace);
+            Throwable unwrappedException = unwrapException(t);
+            StringWriter swriter = new StringWriter();
+            PrintWriter pwriter = new PrintWriter(swriter);
+            t.printStackTrace(pwriter);
+            String stackTrace = swriter.getBuffer().toString();
+            log.error(stackTrace);
+            parameters.getLogger().error(stackTrace);
 
-        parameters.getListener().beforeSetErrorPageAttribute(
-                unwrappedException, request, response);
-        request.setAttribute("exception_message",
-                unwrappedException.getLocalizedMessage());
-        request.setAttribute("user_message", getUserMessage(
-                handler.getMessage(), request.getLocale()));
-        request.setAttribute("stackTrace", stackTrace);
-        request.setAttribute("securityError",
-                ExceptionHelper.isSecurityError(unwrappedException));
-        String dumpedRequest = parameters.getRequestDumper().getDump(request);
-        parameters.getLogger().error(dumpedRequest);
-        request.setAttribute("request_dump", dumpedRequest);
+            parameters.getListener().beforeSetErrorPageAttribute(
+                    unwrappedException, request, response);
+            request.setAttribute("exception_message",
+                    unwrappedException.getLocalizedMessage());
+            request.setAttribute("user_message", getUserMessage(
+                    handler.getMessage(), request.getLocale()));
+            request.setAttribute("stackTrace", stackTrace);
+            request.setAttribute("securityError",
+                    ExceptionHelper.isSecurityError(unwrappedException));
+            String dumpedRequest = parameters.getRequestDumper().getDump(
+                    request);
+            parameters.getLogger().error(dumpedRequest);
+            request.setAttribute("request_dump", dumpedRequest);
 
-        parameters.getListener().beforeForwardToErrorPage(unwrappedException,
-                request, response);
-        if (!response.isCommitted()) {
-            Integer error = handler.getCode();
-            if (error != null) {
-                response.setStatus(error);
+            parameters.getListener().beforeForwardToErrorPage(
+                    unwrappedException, request, response);
+            if (!response.isCommitted()) {
+                Integer error = handler.getCode();
+                if (error != null) {
+                    response.setStatus(error);
+                }
+                String errorPage = handler.getPage();
+                errorPage = (errorPage == null) ? parameters.getDefaultErrorPage()
+                        : errorPage;
+                request.getRequestDispatcher(errorPage).forward(request,
+                        response);
+                FacesContext fContext = FacesContext.getCurrentInstance();
+                if (fContext != null) {
+                    fContext.responseComplete();
+                } else {
+                    log.error("Cannot set response complete: faces context is null");
+                }
+            } else {
+                log.error("Cannot forward to error page: "
+                        + "response is already commited");
+                throw new ServletException(t);
             }
-            String errorPage = handler.getPage();
-            errorPage = (errorPage == null) ? parameters.getDefaultErrorPage()
-                    : errorPage;
-            request.getRequestDispatcher(errorPage).forward(request, response);
             parameters.getListener().afterDispatch(unwrappedException, request,
                     response);
-        } else {
-            log.error("Cannot forward to error page: "
-                    + "response is already commited");
+        } catch (Throwable newError) {
+            throw new ServletException(newError);
         }
     }
 
diff --git a/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/NuxeoExceptionFilter.java b/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/NuxeoExceptionFilter.java
--- a/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/NuxeoExceptionFilter.java
+++ b/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/web/common/exceptionhandling/NuxeoExceptionFilter.java
@@ -44,7 +44,6 @@
     private static final Log log = LogFactory.getLog(NuxeoExceptionFilter.class);
 
     public void init(FilterConfig filterConfig) throws ServletException {
-
         try {
             getHandler();
         } catch (ServletException e) {
@@ -53,7 +52,7 @@
     }
 
     protected NuxeoExceptionHandler getHandler() throws ServletException {
-        if (exceptionHandler==null) {
+        if (exceptionHandler == null) {
             ExceptionHandlingService service;
             try {
                 service = Framework.getService(ExceptionHandlingService.class);
@@ -80,10 +79,16 @@
                 if (log.isDebugEnabled()) {
                     log.debug("Initial exception", t);
                 }
-                handleException((HttpServletRequest) request,
-                        (HttpServletResponse) response, t);
+                try {
+                    handleException((HttpServletRequest) request,
+                            (HttpServletResponse) response, t);
+                } catch (Throwable newThrowable) {
+                    throw new ServletException(newThrowable);
+                }
+            } else {
+                // avoid looping over exception mechanism
+                throw new ServletException(t);
             }
-            throw new ServletException(t);
         }
     }
 
