Index: trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java	(revision 8388)
+++ trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java	(revision 8389)
@@ -20,4 +20,5 @@
     private static final String LAST_MODIFICATION = "lastModification";
     private static final String EXPIRATION_TIME = "expirationTime";
+    private static final String HTTP_RESPONSE_CODE = "httpResponceCode";
 
     /**
@@ -30,4 +31,5 @@
         attrs.put(LAST_MODIFICATION, "0");
         attrs.put(EXPIRATION_TIME, "0");
+        attrs.put(HTTP_RESPONSE_CODE, "200");
     }
 
@@ -46,6 +48,11 @@
 
     private long getLongAttr(String key) {
+        String val = attrs.get(key);
+        if (val == null) {
+            attrs.put(key,  "0");
+            return 0;
+        }
         try {
-            return Long.parseLong(attrs.get(key));
+            return Long.parseLong(val);
         } catch (NumberFormatException e) {
             attrs.put(key, "0");
@@ -67,3 +74,11 @@
     }
 
+    public void setResponseCode(int responseCode) {
+        attrs.put(HTTP_RESPONSE_CODE, Integer.toString(responseCode));
+    }
+
+    public int getResponseCode() {
+        return (int) getLongAttr(HTTP_RESPONSE_CODE);
+    }
+
 }
Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 8388)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 8389)
@@ -364,8 +364,12 @@
                     continue;
                 }
+
+                attributes.setResponseCode(urlConn.getResponseCode());
                 byte[] raw = read(urlConn);
 
                 if (!cacheAsEmpty(urlConn.getHeaderFields(), urlConn.getResponseCode(), raw) &&
                         raw != null && raw.length > 0) {
+                    // we need to check cacheEmpty, so for cases, when data is returned, but we want to store
+                    // as empty (eg. empty tile images) to save some space
                     cacheData = createCacheEntry(raw);
                     cache.put(getCacheKey(), cacheData, attributes);
Index: trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 8388)
+++ trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 8389)
@@ -1,4 +1,6 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.imagery;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.io.ByteArrayInputStream;
@@ -273,4 +275,8 @@
                         }
                     }
+                    int httpStatusCode = attributes.getResponseCode();
+                    if (!isNoTileAtZoom() && httpStatusCode >= 400) {
+                        tile.setError(tr("HTTP error {0} when loading tiles", httpStatusCode));
+                    }
                     // no break intentional here
                 case REJECTED:
@@ -313,4 +319,7 @@
                     tile.finishLoading();
                 }
+                if (attributes.getResponseCode() >= 400) {
+                    tile.setError(tr("HTTP error {0} when loading tiles", attributes.getResponseCode()));
+                }
                 return tile;
             } catch (IOException e) {
