I ran into this problem while working on the Apache Pluto project, which makes use of async features. I boiled it down to come up with two test servlets that are available here: https://github.com/msnicklous/AsyncDebug I have reproduced the problem on both Tomcat 8.0.28 and 8.0.32. Problem description: Given Servlet1 and Servlet2 running in separate servlet contexts. Servlet1 contains the following code: PrintWriter writer = resp.getWriter(); writer.append("<h3>Async Debug1</h3>"); AsyncContext actx = req.startAsync(req, resp); actx.dispatch("/WEB-INF/jsp/debug1.jsp"); When Servlet1 is accessed directly, the header "Async Debug 1" along with the contents of debug1.jsp is displayed properly. Servlet2 contains the following code: ServletContext ctx1 = req.getServletContext().getContext("/AsyncDebug1"); RequestDispatcher rd = ctx1.getRequestDispatcher("/Debug"); rd.forward(req, resp); Servlet2 performs a cross-context forward to Servlet1. The Servlet2 web module contains a context.xml file that enables cross-context support. When Servlet2 is accessed, the header "Async Debug 1" is displayed, but the contents of debug1.jsp is not displayed. Also, the log contains the following message: 22-Mar-2016 08:47:58.875 SEVERE [http-apr-8080-exec-2] org.apache.jasper.servlet.JspServlet.handleMissingResource File [/WEB-INF/jsp/debug1.jsp] not found I think this is incorrect behavior. Since Servlet1 initializes the AsyncContext, this behavior would seen to contradict the Servlet Specification 3.1, page 15 where the description for the AsyncContext#dispatch(String path) method states: "The given path is interpreted as relative to the ServletContext that initialized the AsyncContext.". Additional info: by hacking around, I noticed that changing the Servlet1 dispatch call as follows causes the async dispatch to work even when Servlet1 is accessed through a cross-context forward: actx.dispatch(req.getServletContext(), "/WEB-INF/jsp/debug1.jsp"); where 'req' is the HttpServletRequest. Thanks for having a look at this!
Ok, the dispatch should use the specified wrapped request. The fix will be in 7.0.69, 8.0.34, 8.5.1, and 9M5.