Index: trunk/src/org/openstreetmap/josm/tools/Territories.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Territories.java	(revision 15951)
+++ trunk/src/org/openstreetmap/josm/tools/Territories.java	(revision 15952)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.tools;
 
+import static java.util.Optional.ofNullable;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -22,5 +23,4 @@
 import javax.json.Json;
 import javax.json.JsonArray;
-import javax.json.JsonObject;
 import javax.json.JsonString;
 import javax.json.JsonValue;
@@ -163,39 +163,37 @@
     private static void initializeExternalData() {
         taginfoGeofabrikCache = new TreeMap<>();
-        try (CachedFile cf = new CachedFile(Config.getUrls().getJOSMWebsite() + "/remote/geofabrik-index-v1-nogeom.json");
-                InputStream is = cf.getInputStream();
-                JsonParser json = Json.createParser(is)) {
+        initializeExternalData(taginfoGeofabrikCache, "Geofabrik",
+                Config.getUrls().getJOSMWebsite() + "/remote/geofabrik-index-v1-nogeom.json");
+    }
+
+    static void initializeExternalData(Map<String, TaginfoRegionalInstance> cache, String source, String path) {
+        try (CachedFile cf = new CachedFile(path); InputStream is = cf.getInputStream(); JsonParser json = Json.createParser(is)) {
             while (json.hasNext()) {
                 Event event = json.next();
                 if (event == Event.START_OBJECT) {
                     for (JsonValue feature : json.getObject().getJsonArray("features")) {
-                        JsonObject props = feature.asJsonObject().getJsonObject("properties");
-                        if (props != null) {
-                            JsonObject urls = props.getJsonObject("urls");
-                            if (urls != null) {
-                                String taginfo = urls.getString(TAGINFO);
-                                if (taginfo != null) {
-                                    JsonArray iso1 = props.getJsonArray(ISO3166_1_LC);
-                                    JsonArray iso2 = props.getJsonArray(ISO3166_2_LC);
-                                    if (iso1 != null) {
-                                        readExternalTaginfo(taginfo, iso1);
-                                    } else if (iso2 != null) {
-                                        readExternalTaginfo(taginfo, iso2);
-                                    }
-                                }
+                        ofNullable(feature.asJsonObject().getJsonObject("properties")).ifPresent(props ->
+                        ofNullable(props.getJsonObject("urls")).ifPresent(urls ->
+                        ofNullable(urls.getString(TAGINFO)).ifPresent(taginfo -> {
+                            JsonArray iso1 = props.getJsonArray(ISO3166_1_LC);
+                            JsonArray iso2 = props.getJsonArray(ISO3166_2_LC);
+                            if (iso1 != null) {
+                                readExternalTaginfo(cache, taginfo, iso1, source);
+                            } else if (iso2 != null) {
+                                readExternalTaginfo(cache, taginfo, iso2, source);
                             }
-                        }
+                        })));
                     }
                 }
             }
         } catch (IOException | JsonParsingException e) {
-            Logging.trace(e);
-            Logging.warn(tr("Failed to parse taginfo data geofabrik-index-v1-nogeom.json"));
-        }
-    }
-
-    private static void readExternalTaginfo(String taginfo, JsonArray jsonCodes) {
+            Logging.debug(e);
+            Logging.warn(tr("Failed to parse external taginfo data at {0}: {1}", path, e.getMessage()));
+        }
+    }
+
+    private static void readExternalTaginfo(Map<String, TaginfoRegionalInstance> cache, String taginfo, JsonArray jsonCodes, String source) {
         Set<String> isoCodes = jsonCodes.getValuesAs(JsonString.class).stream().map(JsonString::getString).collect(Collectors.toSet());
-        isoCodes.forEach(s -> taginfoGeofabrikCache.put(s, new TaginfoRegionalInstance(taginfo, isoCodes, "Geofabrik")));
+        isoCodes.forEach(s -> cache.put(s, new TaginfoRegionalInstance(taginfo, isoCodes, source)));
     }
 
Index: trunk/test/data/taginfo/geofabrik-index-v1-nogeom-broken.json
===================================================================
--- trunk/test/data/taginfo/geofabrik-index-v1-nogeom-broken.json	(revision 15952)
+++ trunk/test/data/taginfo/geofabrik-index-v1-nogeom-broken.json	(revision 15952)
@@ -0,0 +1,2 @@
+{ "type": "FeatureCollection",
+    "features": [
Index: trunk/test/data/taginfo/geofabrik-index-v1-nogeom.json
===================================================================
--- trunk/test/data/taginfo/geofabrik-index-v1-nogeom.json	(revision 15952)
+++ trunk/test/data/taginfo/geofabrik-index-v1-nogeom.json	(revision 15952)
@@ -0,0 +1,91 @@
+{ "type": "FeatureCollection",
+    "features": [
+        {
+            "type": "Feature",
+            "properties": { 
+                "id" : "afghanistan",
+                "parent" : "asia",
+                "iso3166-1:alpha2" : [ "AF" ],
+                "name" : "Afghanistan",
+                "urls" : {
+                    "pbf" : "https://download.geofabrik.de/asia/afghanistan-latest.osm.pbf",
+                    "bz2" : "https://download.geofabrik.de/asia/afghanistan-latest.osm.bz2",
+                    "shp" : "https://download.geofabrik.de/asia/afghanistan-latest-free.shp.zip",
+                    "pbf-internal" : "https://osm-internal.download.geofabrik.de/asia/afghanistan-latest-internal.osm.pbf",
+                    "history" : "https://osm-internal.download.geofabrik.de/asia/afghanistan-internal.osh.pbf",
+                    "taginfo" : "https://taginfo.geofabrik.de/asia/afghanistan/",
+                    "updates" : "https://download.geofabrik.de/asia/afghanistan-updates"
+                }
+            }
+        },
+        {
+            "type": "Feature",
+            "properties": { 
+                "id" : "africa",
+                "name" : "Africa",
+                "urls" : {
+                    "pbf" : "https://download.geofabrik.de/africa-latest.osm.pbf",
+                    "bz2" : "https://download.geofabrik.de/africa-latest.osm.bz2",
+                    "pbf-internal" : "https://osm-internal.download.geofabrik.de/africa-latest-internal.osm.pbf",
+                    "history" : "https://osm-internal.download.geofabrik.de/africa-internal.osh.pbf",
+                    "taginfo" : "https://taginfo.geofabrik.de/africa/",
+                    "updates" : "https://download.geofabrik.de/africa-updates"
+                }
+            }
+        },
+        {
+            "type": "Feature",
+            "properties": { 
+                "id" : "albania",
+                "parent" : "europe",
+                "iso3166-1:alpha2" : [ "AL" ],
+                "name" : "Albania",
+                "urls" : {
+                    "pbf" : "https://download.geofabrik.de/europe/albania-latest.osm.pbf",
+                    "bz2" : "https://download.geofabrik.de/europe/albania-latest.osm.bz2",
+                    "shp" : "https://download.geofabrik.de/europe/albania-latest-free.shp.zip",
+                    "pbf-internal" : "https://osm-internal.download.geofabrik.de/europe/albania-latest-internal.osm.pbf",
+                    "history" : "https://osm-internal.download.geofabrik.de/europe/albania-internal.osh.pbf",
+                    "taginfo" : "https://taginfo.geofabrik.de/europe/albania/",
+                    "updates" : "https://download.geofabrik.de/europe/albania-updates"
+                }
+            }
+        },
+        {
+            "type": "Feature",
+            "properties": { 
+                "id" : "alberta",
+                "parent" : "canada",
+                "iso3166-2" : [ "CA-AB" ],
+                "name" : "Alberta",
+                "urls" : {
+                    "pbf" : "https://download.geofabrik.de/north-america/canada/alberta-latest.osm.pbf",
+                    "bz2" : "https://download.geofabrik.de/north-america/canada/alberta-latest.osm.bz2",
+                    "shp" : "https://download.geofabrik.de/north-america/canada/alberta-latest-free.shp.zip",
+                    "pbf-internal" : "https://osm-internal.download.geofabrik.de/north-america/canada/alberta-latest-internal.osm.pbf",
+                    "history" : "https://osm-internal.download.geofabrik.de/north-america/canada/alberta-internal.osh.pbf",
+                    "taginfo" : "https://taginfo.geofabrik.de/north-america/canada/alberta/",
+                    "updates" : "https://download.geofabrik.de/north-america/canada/alberta-updates"
+                }
+            }
+        },
+        {
+            "type": "Feature",
+            "properties": { 
+                "id" : "israel-and-palestine",
+                "parent" : "asia",
+                "iso3166-1:alpha2" : [ "PS","IL" ],
+                "name" : "Israel and Palestine",
+                "urls" : {
+                    "pbf" : "https://download.geofabrik.de/asia/israel-and-palestine-latest.osm.pbf",
+                    "bz2" : "https://download.geofabrik.de/asia/israel-and-palestine-latest.osm.bz2",
+                    "shp" : "https://download.geofabrik.de/asia/israel-and-palestine-latest-free.shp.zip",
+                    "pbf-internal" : "https://osm-internal.download.geofabrik.de/asia/israel-and-palestine-latest-internal.osm.pbf",
+                    "history" : "https://osm-internal.download.geofabrik.de/asia/israel-and-palestine-internal.osh.pbf",
+                    "taginfo" : "https://taginfo.geofabrik.de/asia/israel-and-palestine/",
+                    "updates" : "https://download.geofabrik.de/asia/israel-and-palestine-updates"
+                }
+            }
+        }
+     ]
+}
Index: trunk/test/unit/org/openstreetmap/josm/tools/TerritoriesTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/tools/TerritoriesTest.java	(revision 15951)
+++ trunk/test/unit/org/openstreetmap/josm/tools/TerritoriesTest.java	(revision 15952)
@@ -2,8 +2,17 @@
 package org.openstreetmap.josm.tools;
 
+import static java.util.Collections.singleton;
 import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
 
 import org.junit.Rule;
 import org.junit.Test;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
@@ -45,3 +54,40 @@
         }
     }
+
+    /**
+     * Test of {@link Territories#initializeExternalData} - nominal case
+     */
+    @Test
+    public void testTaginfoGeofabrik_nominal() {
+        Map<String, TaginfoRegionalInstance> cache = new TreeMap<>();
+        Territories.initializeExternalData(cache, "foo", TestUtils.getTestDataRoot() + "/taginfo/geofabrik-index-v1-nogeom.json");
+        assertEquals(5, cache.size());
+        checkTaginfoInstance(cache.get("AF"), singleton("AF"), "https://taginfo.geofabrik.de/asia/afghanistan/");
+        checkTaginfoInstance(cache.get("AL"), singleton("AL"), "https://taginfo.geofabrik.de/europe/albania/");
+        checkTaginfoInstance(cache.get("CA-AB"), singleton("CA-AB"), "https://taginfo.geofabrik.de/north-america/canada/alberta/");
+        Set<String> israelAndPalestine = new HashSet<>(Arrays.asList("PS", "IL"));
+        checkTaginfoInstance(cache.get("PS"), israelAndPalestine, "https://taginfo.geofabrik.de/asia/israel-and-palestine/");
+        checkTaginfoInstance(cache.get("IL"), israelAndPalestine, "https://taginfo.geofabrik.de/asia/israel-and-palestine/");
+    }
+
+    private static void checkTaginfoInstance(TaginfoRegionalInstance instance, Set<String> expectedIsoCodes, String expectedUrl) {
+        assertEquals(expectedIsoCodes, instance.getIsoCodes());
+        assertEquals("foo", instance.getSuffix());
+        assertEquals(expectedUrl, instance.getUrl());
+    }
+
+    /**
+     * Test of {@link Territories#initializeExternalData} - broken contents
+     */
+    @Test
+    public void testTaginfoGeofabrik_broken() {
+        Map<String, TaginfoRegionalInstance> cache = new TreeMap<>();
+        Logging.clearLastErrorAndWarnings();
+        Territories.initializeExternalData(cache, "foo", TestUtils.getTestDataRoot() + "taginfo/geofabrik-index-v1-nogeom-broken.json");
+        assertTrue(cache.isEmpty());
+        assertEquals("W: Failed to parse external taginfo data at test/data/taginfo/geofabrik-index-v1-nogeom-broken.json: " +
+                "Invalid token=EOF at (line no=3, column no=49, offset=97). Expected tokens are: " +
+                "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL, SQUARECLOSE]",
+                Logging.getLastErrorAndWarnings().get(0));
+    }
 }
