Index: /trunk/scripts/SyncEditorLayerIndex.java
===================================================================
--- /trunk/scripts/SyncEditorLayerIndex.java	(revision 18988)
+++ /trunk/scripts/SyncEditorLayerIndex.java	(revision 18989)
@@ -1,3 +1,4 @@
 // License: GPL. For details, see LICENSE file.
+
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.commons.lang3.StringUtils.isBlank;
@@ -38,12 +39,4 @@
 import java.util.stream.Collectors;
 
-import jakarta.json.Json;
-import jakarta.json.JsonArray;
-import jakarta.json.JsonNumber;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonReader;
-import jakarta.json.JsonString;
-import jakarta.json.JsonValue;
-
 import org.openstreetmap.gui.jmapviewer.Coordinate;
 import org.openstreetmap.josm.data.Preferences;
@@ -66,4 +59,12 @@
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
+
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
 
 /**
@@ -500,4 +501,7 @@
 
         for (ImageryInfo e : josmEntries) {
+            if (!e.isValid()) {
+                myprintln("~~~ JOSM-Entry missing fields (" + String.join(", ", e.getMissingFields()) + "): " + getDescription(e));
+            }
             if (isBlank(getUrl(e))) {
                 myprintln("~~~ JOSM-Entry without URL: " + getDescription(e));
Index: /trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 18988)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 18989)
@@ -20,7 +20,4 @@
 import java.util.stream.Collectors;
 
-import jakarta.json.Json;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonReader;
 import javax.swing.ImageIcon;
 
@@ -39,4 +36,8 @@
 import org.openstreetmap.josm.tools.StreamUtils;
 import org.openstreetmap.josm.tools.Utils;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
 
 /**
@@ -205,4 +206,6 @@
         }
     }
+
+    private static final String[] EMPTY_STRING = new String[0];
 
     private double pixelPerDegree;
@@ -567,5 +570,5 @@
      * Check if this object equals another ImageryInfo with respect to the properties
      * that get written to the preference file.
-     *
+     * <p>
      * The field {@link #pixelPerDegree} is ignored.
      *
@@ -965,4 +968,47 @@
 
     /**
+     * Check to see if this info is valid (the XSD is overly permissive due to limitations of the XSD syntax).
+     * @return {@code true} if this info is valid
+     * @see ImageryInfo#getMissingFields()
+     * @since 18989
+     */
+    public boolean isValid() {
+        return this.getName() != null &&
+                this.getId() != null &&
+                this.getSourceType() != null &&
+                this.getUrl() != null &&
+                this.getImageryCategory() != null;
+    }
+
+    /**
+     * Get the missing fields for this info
+     * @return The missing fields, or an empty array
+     * @see ImageryInfo#isValid()
+     * @since 18989
+     */
+    public String[] getMissingFields() {
+        if (this.isValid()) {
+            return EMPTY_STRING;
+        }
+        List<String> missingFields = new ArrayList<>();
+        if (this.getName() == null) {
+            missingFields.add("name");
+        }
+        if (this.getId() == null) {
+            missingFields.add("id");
+        }
+        if (this.getSourceType() == null) {
+            missingFields.add("type");
+        }
+        if (this.getUrl() == null) {
+            missingFields.add("url");
+        }
+        if (this.getImageryCategory() == null) {
+            missingFields.add("category");
+        }
+        return missingFields.toArray(new String[0]);
+    }
+
+    /**
      * Return the sorted list of activated source IDs.
      * @return sorted list of activated source IDs
Index: /trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java	(revision 18988)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java	(revision 18989)
@@ -167,4 +167,6 @@
                 reader.setFastFail(fastFail);
                 Collection<ImageryInfo> result = reader.parse();
+                // See #23485 (remove invalid source entries)
+                result.removeIf(info -> !info.isValid());
                 newLayers.addAll(result);
             } catch (IOException ex) {
