Index: /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 13229)
+++ /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 13230)
@@ -16,4 +16,6 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
@@ -50,4 +52,12 @@
     protected static final long ABSOLUTE_EXPIRE_TIME_LIMIT = TimeUnit.DAYS.toMillis(365);
 
+    // Pattern to detect Tomcat error message. Be careful with change of format:
+    // CHECKSTYLE.OFF: LineLength
+    // https://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java?r1=1740707&r2=1779641&pathrev=1779641&diff_format=h
+    // CHECKSTYLE.ON: LineLength
+    protected static final Pattern TOMCAT_ERR_MESSAGE = Pattern.compile(
+        ".*<p><b>[^<]+</b>[^<]+</p><p><b>[^<]+</b> (?:<u>)?([^<]*)(?:</u>)?</p><p><b>[^<]+</b> (?:<u>)?[^<]*(?:</u>)?</p>.*",
+        Pattern.CASE_INSENSITIVE);
+
     /**
      * maximum download threads that will be started
@@ -74,6 +84,4 @@
             Utils.newThreadFactory("JCS-downloader-%d", Thread.NORM_PRIORITY)
             );
-
-
 
     private static final ConcurrentMap<String, Set<ICachedLoaderListener>> inProgress = new ConcurrentHashMap<>();
@@ -359,4 +367,15 @@
                 } else {
                     raw = new byte[]{};
+                    try {
+                        String data = urlConn.fetchContent();
+                        if (!data.isEmpty()) {
+                            Matcher m = TOMCAT_ERR_MESSAGE.matcher(data);
+                            if (m.matches()) {
+                                attributes.setErrorMessage(m.group(1).replace("'", "''"));
+                            }
+                        }
+                    } catch (IOException e) {
+                        Logging.warn(e);
+                    }
                 }
 
@@ -390,5 +409,5 @@
             return doCache;
         } catch (IOException e) {
-            Logging.debug("JCS - IOExecption during communication with server for: {0}", getUrlNoException());
+            Logging.debug("JCS - IOException during communication with server for: {0}", getUrlNoException());
             if (isObjectLoadable()) {
                 return true;
Index: /trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java	(revision 13229)
+++ /trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java	(revision 13230)
@@ -4,4 +4,5 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
@@ -9,4 +10,5 @@
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
 
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
@@ -171,3 +173,26 @@
         return JCSCacheManager.getCache("test");
     }
+
+    /**
+     * Test that error message sent by Tomcat can be parsed.
+     */
+    @Test
+    public void testTomcatErrorMessage() {
+        Matcher m = JCSCachedTileLoaderJob.TOMCAT_ERR_MESSAGE.matcher(
+            "<html><head><title>Apache Tomcat/DGFiP - Rapport d''erreur</title><style><!--"+
+                "H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} "+
+                "H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} "+
+                "H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} "+
+                "BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} "+
+                "B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} "+
+                "P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}"+
+                "A {color : black;}A.name {color : black;}HR {color : #525D76;}"+
+            "--></style> </head><body><h1>Etat HTTP 400 - La commune demandée n'existe pas ou n'est pas accessible.</h1>"+
+            "<HR size=\"1\" noshade=\"noshade\">"+
+            "<p><b>type</b> Rapport d''état</p><p><b>message</b> <u>La commune demandée n'existe pas ou n'est pas accessible.</u></p>"+
+            "<p><b>description</b> <u>La requête envoyée par le client était syntaxiquement incorrecte.</u></p>"+
+            "<HR size=\"1\" noshade=\"noshade\"><h3>Apache Tomcat/DGFiP</h3></body></html>");
+        assertTrue(m.matches());
+        assertEquals("La commune demandée n'existe pas ou n'est pas accessible.", m.group(1));
+    }
 }
