Index: trunk/src/org/openstreetmap/josm/data/imagery/ImageryPatterns.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/ImageryPatterns.java	(revision 18378)
+++ trunk/src/org/openstreetmap/josm/data/imagery/ImageryPatterns.java	(revision 18380)
@@ -9,8 +9,10 @@
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
+import org.openstreetmap.josm.spi.preferences.Config;
 
 /**
@@ -94,11 +96,24 @@
         if (id != null && url != null) {
             final Matcher matcher = PATTERN_API_KEY.matcher(url);
-            if (matcher.matches()) {
+            if (matcher.find()) {
                 try {
-                    final String apiKey = FeatureAdapter.retrieveApiKey(id);
-                    return matcher.replaceAll(apiKey);
-                } catch (IOException | NullPointerException e) {
+                    return Optional.ofNullable(FeatureAdapter.retrieveApiKey(id))
+                            .map(matcher::replaceAll)
+                            /* None of the configured API key sites had an API key for the id. */
+                            .orElseThrow(() -> {
+                                // Give a more complete error message so that users can fix the problem without
+                                // opening a bug report. Hopefully.
+                                final String message;
+                                if (Config.getPref().getKeySet().contains("apikey.sites")) {
+                                    message = tr("Advanced preference ''{0}'' is not default. Please consider resetting it.", "apikey.sites");
+                                } else {
+                                    message = tr("API key for imagery with id={0} may not be available.", id);
+                                }
+                                return new IOException(message);
+                            });
+                } catch (IOException e) {
                     // Match rough behavior in JMapViewer TemplatedTMSTileSource, but with better error message.
-                    throw new IllegalArgumentException(tr("Could not retrieve API key for imagery with id={0}. Cannot add layer.", id), e);
+                    throw new IllegalArgumentException(tr("Could not retrieve API key for imagery with id={0}. Cannot add layer.\n{1}",
+                            id, e.getMessage()), e);
                 }
             }
