Quando c'è una eccezione, il servlet container cerca di fare un forward alla pagina di errore che hai indicato. La questione generale è che un forward può essere fatto solo se la response non è stata ancora "committata", ovvero se non è stato ancora inviato fisicamente alcun byte al client. Le pagine JSP usano un buffer (la dimensione è specifica per il server ma in genere intorno a 8kbyte). Finché non superi questa soglia, se c'è da fare un forward, viene buttato via il contenuto del buffer e si può passare alla pagina di errore, non avendo ancora inviato fisicamente nulla.
Se superi tale soglia, il container invia fisicamente i dati al client e il forward non è più possibile (e oltretutto lancia IllegalStateException). D’altronde, se lo facesse sarebbe un macello ... un pezzo di una pagina, un pezzo di un'altra! (ovvero HTML completamente sballato)
Il buffer si può anche espandere con una semplice direttiva nel <%@ page %> ma .... il tuo approccio non è comunque dei migliori. Le pagine JSP non dovrebbero compiere (né direttamente né indirettamente) della logica di elaborazione che può causare errori.