If you issue a response.setStatus(404) from a servlet, you expect as per spec that the response is left untouched. No error page written. There is sendError for that. Unfortunately, ErrorReportValve reacts on line 158 > if ((statusCode < 400) || (response.getContentCount() > 0)) > return; If you take a look at the StandardHostValve, it invokes error handling on line 316 > if (!response.isError()) > return; On errors only (correct behavior). The ErrorReportValve must react on response.isError() == true only. Regardless of the status code or the content count. The Javadoc does not limit this to status codes >= 400 but is says that reponse.sendError() has to clears buffers. As far I understand that, regardless of the response body is disposed and the error reponse is always written.
Fixed in trunk and 7.0.x and will be included in 7.0.34 onwards.
Opps. Need to keep this open until 6.0x. is fixed.
Proposed for 6.0.x
Fixed in Tomcat 6 by r1417925 , will be in 6.0.37 onwards.