20

We have tomcat 9 web server in production. The problem we are facing is we want to show the custom error page for our application if tomcat receives any malformed URL as follows

http://URL/|

or

http://URL/[

I have added error page tag in web.xml of tomcat application server as follows

<error-page>
   <error-code>400</error-code>
   <location>/error.html</location>
 </error-page>
 <error-page>
   <error-code>404</error-code>
   <location>/error.html</location>
 </error-page>

and we have error.html in our application ROOT folder in webapps directory of tomcat.

Whenever the user tries to request any nonexistent webpage he receives error page correctly corresponding to 404 error code as specified above.

Real Problem is tomcat not able to redirect to error.html when the user enters malformed URL in the browser like http://URL/|

Tomcat is showing the default 400 bad request error page instead of the custom error page.

Pawan Patil
  • 1,067
  • 5
  • 20
  • 46

4 Answers4

23

This is not a bug, it is a configuration issue.

Tomcat 9 has improved the error handling so that more errors, particularly those those occur before request processing starts, are passed to the standard error handling mechanism rather than just returning an error code.

In the case of malformed URIs, it is not possible for Tomcat to parse the URI hence the URI cannot be mapped to a web application. Tomcat is, therefore, unable to trigger the application level error handling because it cannot identify an application. In this case, the error is handled by the ErrorReportValve which can be configured in server.xml.

A recent(ish) addition to the ErrorReportValve is the ability to define static web pages (i.e. no Servlets or JSPs, just HTML) per status code and/or Exception type in a similar manner to the per web application error page configuration.

Example Error Report Valve:

<Valve className="org.apache.catalina.valves.ErrorReportValve"
        errorCode.400="webapps/ROOT/error400.html"
        errorCode.0="webapps/ROOT/errorOthers.html"
        showReport="false"
        showServerInfo="false" />
Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
Mark Thomas
  • 16,339
  • 1
  • 39
  • 60
  • 2
    I can't seem to find any examples in the Tomcat documentation or anywhere else of how to configure the ErrorReportValve to return pre-defined static HTML pages. Can you point me to any examples? – CFL_Jeff Jun 24 '19 at 12:25
  • @CFL_Jeff. See https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#Error_Report_Valve – gordon613 Jan 31 '21 at 15:06
  • Yes, now implemented it for Tomcat 9.0.53 and it works. Ta. I suggest paying attention to special value of `errorCode.0`. That way you can centrally secure the whole server if it has many contexts. – Paul Uszak Sep 24 '21 at 13:15
  • This also works in [Tomcat 8.5](https://tomcat.apache.org/tomcat-8.5-doc/config/valve.html#Error_Report_Valve). – Matt Sep 22 '22 at 20:42
  • @Paul Uszak , this answer is not working for me though I have the customhtml file for error 400 at the location mentioned in your answer. Only the default tomcat error page for 400 keeps popping up. I want my custom400error.html to get rendered at screen. Help on this – MdBasha Nov 03 '22 at 09:41
  • @MdBasha Hiya. Just confirmed that it's showing my own 404 error page for all 400 errors. Do you have the valve in server.xml? That's where it has to go (not web.xml). You can force your own 400 errors by GETting www.home.com/%foo. – Paul Uszak Nov 03 '22 at 10:39
  • @MdBasha I have " " – Paul Uszak Nov 03 '22 at 10:41
  • No I am using this in server.xml only from the start but the line errorCode.400 is not referring to the path mentioned and displaying the html as expected. Tomcat’s default is popping up every time. Could please explain your line ‘ force your own 400 errors by GETting www.home.com/%foo’ ? – MdBasha Nov 03 '22 at 12:59
  • @Matt I am also using Tomcat 8.5.42 please give me the configuration For errorCode.400 – MdBasha Nov 04 '22 at 07:12
  • @PaulUszak please confirm your production tomcat version? – MdBasha Nov 04 '22 at 07:12
  • @MdBasha Still 9.0.53 @ www.reallyreallyrandom.com. But to all out there, it's a fully patched system. – Paul Uszak Nov 04 '22 at 13:29
  • @MdBasha `` (note no errorCode.0 entry) – Matt Nov 04 '22 at 17:13
9

Below is sample configuration that follows https://stackoverflow.com/a/55702749/2532710 to save someone else time. In server.xml inside Host tag:

  <Valve className="org.apache.catalina.valves.ErrorReportValve"
        errorCode.400="webapps/ROOT/error400.html"
        errorCode.0="webapps/ROOT/errorOthers.html"
        showReport="false"
        showServerInfo="false" />

Put static html error400.html ... errorOthers.html in webapps/ROOT of CATALINA_BASE.

kosolapyj
  • 121
  • 1
  • 3
  • Where is CATALINA_BASE? – CodificadorD Feb 02 '22 at 13:34
  • @CodificadorD - If you did not define it, it is defaulted to CATALINA_HOME – kosolapyj Feb 13 '22 at 22:37
  • @kosolapyj this is not working for me though I have the html file at the location mentioned in your answer. Only the default error page for 400 keeps popping up. I want my custom400error.html to get rendered at screen. Help on this – MdBasha Nov 03 '22 at 09:34
1

Previous solutions were not working in my case.

According to the Tomcat doc, the valve component can put be into the container Engine, Host, or Context. Tried everything without success regarding this specific error 400 (while others errors are handled as expected).

Finally I found the missing element in that enigma:

To be efficient, oddly enough, the Error Report Valve has to be put in the host container defined as the defaultHost of the catalina engine, even if it is not the targeted host.

server.xml example: handle error 400 Bad requests for "some-cats.com" and "some-dogs.com" as well

<Engine name="Catalina" defaultHost="www.some-dogs.com">
    <!--     NO EFFECT ON ERROR PAGE 400
    <Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" /> 
    -->
    <Host name="www.some-cats.com">      
        <!--     NO EFFECT ON ERROR PAGE 400
        <Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" /> 
        -->
        ...
    </Host>
    <Host name="www.some-dogs.com">
        <!--  HERE IS THE RIGHT PLACE FOR ERROR PAGE 400-->
        <Valve className="org.apache.catalina.valves.ErrorReportValve" errorCode.0="path/error.html" showReport="false" showServerInfo="false" />
        ...
    </Host>
</Engine>

Tested on tomcat 8.5.84 and 9.0.70

Of course if you just have one host, you don't have this problem.

Glucide
  • 279
  • 2
  • 5
0

You can write your own error page https://aspiresoftware.in/blog/catalinatomcat-custom-error-report-valve-to-handle-errors-exceptions/

You have to put your jar in tomcat lib.

  • this is not working for me though I have the html file and jar file at the location mentioned in your answer. Only the default error page for 400 keeps popping up. I want my custom400error.html to get rendered at screen. Help on this – MdBasha Nov 03 '22 at 09:35