Index: trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java	(revision 14269)
+++ trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java	(revision 14270)
@@ -7,4 +7,5 @@
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -29,4 +30,5 @@
     private static final String HTTP_RESPONSE_CODE = "httpResponseCode";
     private static final String ERROR_MESSAGE = "errorMessage";
+    private static final String EXCEPTION = "exception";
     // this contains all of the above
     private static final Set<String> RESERVED_KEYS = new HashSet<>(Arrays.asList(
@@ -36,5 +38,6 @@
         EXPIRATION_TIME,
         HTTP_RESPONSE_CODE,
-        ERROR_MESSAGE
+        ERROR_MESSAGE,
+        EXCEPTION
     ));
 
@@ -195,3 +198,31 @@
         attrs.put(ERROR_MESSAGE, message);
     }
+
+    /**
+     * @param e exception that caused error
+     *
+     */
+    public void setException(Exception e) {
+        attrs.put(EXCEPTION, e.getClass().getCanonicalName());
+    }
+
+    /**
+     * @return Optional exception that was thrown when fetching resource
+     *
+     */
+    public Optional<Class<? extends Exception>> getException() {
+        String className = attrs.get(EXCEPTION);
+        if (className == null) {
+            return Optional.empty();
+        }
+        try {
+            Class<?> klass = Class.forName(className);
+            if (Exception.class.isAssignableFrom(klass)) {
+                return Optional.of(klass.asSubclass(Exception.class));
+            }
+        } catch (ClassNotFoundException | ClassCastException ex) {
+            // NOOP
+        }
+        return Optional.empty();
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 14269)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 14270)
@@ -392,4 +392,5 @@
             attributes.setResponseCode(404);
             attributes.setError(e);
+            attributes.setException(e);
             boolean doCache = isResponseLoadable(null, 404, null) || cacheAsEmpty();
             if (doCache) {
@@ -404,4 +405,5 @@
             } else {
                 attributes.setError(e);
+                attributes.setException(e);
                 attributes.setResponseCode(599); // set dummy error code, greater than 500 so it will be not cached
                 return false;
@@ -410,4 +412,5 @@
         } catch (InterruptedException e) {
             attributes.setError(e);
+            attributes.setException(e);
             Logging.logWithStackTrace(Logging.LEVEL_WARN, e, "JCS - Exception during download {0}", getUrlNoException());
             Thread.currentThread().interrupt();
Index: trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 14269)
+++ trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 14270)
@@ -6,4 +6,5 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
@@ -226,4 +227,8 @@
                 tile.setLoaded(false); // treat 500 errors as temporary and try to load it again
             }
+            // treat SocketTimeoutException as transient error
+            attributes.getException()
+            .filter(x -> x.isAssignableFrom(SocketTimeoutException.class))
+            .ifPresent(x -> tile.setLoaded(false));
         } else {
             tile.setError(tr("Problem loading tile"));
