Index: /applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java	(revision 36236)
+++ /applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java	(revision 36237)
@@ -5,5 +5,4 @@
 import static org.openstreetmap.josm.tools.I18n.trn;
 
-import java.net.HttpURLConnection;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -47,8 +46,6 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
-import org.openstreetmap.josm.io.OsmApiException;
 import org.openstreetmap.josm.io.OsmServerChangesetReader;
 import org.openstreetmap.josm.io.OsmTransferException;
-import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -204,25 +201,4 @@
     }
 
-    private static void readObjectVersion(OsmServerMultiObjectReader rdr, PrimitiveId id, int version, ProgressMonitor progressMonitor)
-            throws OsmTransferException {
-        boolean readOK = false;
-        while (!readOK && version >= 1) {
-            try {
-                rdr.readObject(id, version, progressMonitor.createSubTaskMonitor(1, true));
-                readOK = true;
-            } catch (OsmApiException e) {
-                if (e.getResponseCode() != HttpURLConnection.HTTP_FORBIDDEN) {
-                    throw e;
-                }
-                String message = "Version " + version + " of " + id + " is unauthorized";
-                Logging.info(version <= 1 ? message : message + ", requesting previous one");
-                version--;
-            }
-        }
-        if (!readOK) {
-            Logging.warn("Cannot retrieve any previous version of "+id);
-        }
-    }
-
     /**
      * fetch objects that were updated or deleted by changeset
@@ -238,7 +214,7 @@
                         trn("Downloading history for {0} object", "Downloading history for {0} objects", num, num)), num + 1);
         try {
-            HashMap<Long, Integer> nodeList = new HashMap<>(),
-                    wayList = new HashMap<>(),
-                    relationList = new HashMap<>();
+            HashMap<Long, Integer> nodeList = new HashMap<>();
+            HashMap<Long, Integer> wayList = new HashMap<>();
+            HashMap<Long, Integer> relationList = new HashMap<>();
 
             for (HashSet<HistoryOsmPrimitive> collection : Arrays.asList(updated, deleted)) {
@@ -256,21 +232,7 @@
                 }
             }
-            rdr.readMultiObjects(OsmPrimitiveType.NODE, nodeList, progressMonitor);
-            rdr.readMultiObjects(OsmPrimitiveType.WAY, wayList, progressMonitor);
-            rdr.readMultiObjects(OsmPrimitiveType.RELATION, relationList, progressMonitor);
-            if (progressMonitor.isCanceled()) return;
-            // If multi-read failed, retry with regular read
-            for (Map.Entry<Long, Integer> entry : nodeList.entrySet()) {
-                if (progressMonitor.isCanceled()) return;
-                readObjectVersion(rdr, new SimplePrimitiveId(entry.getKey(), OsmPrimitiveType.NODE), entry.getValue(), progressMonitor);
-            }
-            for (Map.Entry<Long, Integer> entry : wayList.entrySet()) {
-                if (progressMonitor.isCanceled()) return;
-                readObjectVersion(rdr, new SimplePrimitiveId(entry.getKey(), OsmPrimitiveType.WAY), entry.getValue(), progressMonitor);
-            }
-            for (Map.Entry<Long, Integer> entry : relationList.entrySet()) {
-                if (progressMonitor.isCanceled()) return;
-                readObjectVersion(rdr, new SimplePrimitiveId(entry.getKey(), OsmPrimitiveType.RELATION), entry.getValue(), progressMonitor);
-            }
+            rdr.readMultiObjectsOrNextOlder(OsmPrimitiveType.NODE, nodeList, progressMonitor);
+            rdr.readMultiObjectsOrNextOlder(OsmPrimitiveType.WAY, wayList, progressMonitor);
+            rdr.readMultiObjectsOrNextOlder(OsmPrimitiveType.RELATION, relationList, progressMonitor);
             if (progressMonitor.isCanceled()) return;
             nds = rdr.parseOsm(progressMonitor.createSubTaskMonitor(1, true));
@@ -513,8 +475,11 @@
         // Remove primitives where we already know the LatLon.
         nodes.removeIf(n -> {
+            if (n.isDeleted() || n.isLatLonKnown())
+                return true;
             PrimitiveId id = n.getPrimitiveId();
             OsmPrimitive p = ds.getPrimitiveById(id);
-            return !(p instanceof Node) || ((Node) p).isLatLonKnown();
+            return !(p instanceof Node) || ((Node) p).isLatLonKnown() || p.getVersion() <= 1;
         });
+
         progressMonitor.worked(num - nodes.size());
 
@@ -524,4 +489,5 @@
                 .collect(Collectors.toMap(AbstractPrimitive::getUniqueId,
                         id -> Math.max(1, Optional.ofNullable(ds.getPrimitiveById(id)).orElse(id).getVersion() - 1)));
+
         try {
             while (!versionMap.isEmpty()) {
@@ -529,10 +495,10 @@
                 final ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(num, false);
                 subMonitor.beginTask(tr("Fetching multi-objects"), versionMap.size());
-                rds.readMultiObjects(OsmPrimitiveType.NODE, versionMap, subMonitor);
+                rds.readMultiObjectsOrNextOlder(OsmPrimitiveType.NODE, versionMap, subMonitor);
                 subMonitor.finishTask();
                 final DataSet history = rds.parseOsm(progressMonitor.createSubTaskMonitor(0, false));
+                ds.update(() -> updateNodes(progressMonitor, nodes, versionMap, history));
+                versionMap.values().removeIf(i -> i <= 1);
                 versionMap.replaceAll((key, value) -> value - 1);
-                versionMap.values().removeIf(i -> i <= 0);
-                ds.update(() -> updateNodes(progressMonitor, nodes, versionMap, history));
                 if (progressMonitor.isCanceled()) {
                     break;
@@ -555,9 +521,12 @@
             if (!n.isDeleted() && !n.isLatLonKnown()) {
                 final Node historyNode = (Node) history.getPrimitiveById(n);
-                if (historyNode != null && historyNode.isLatLonKnown()
-                        && changeset.getClosedAt().isAfter(historyNode.getInstant())) {
-                    n.load(historyNode.save());
-                    versionMap.remove(n.getUniqueId());
-                    progressMonitor.worked(1);
+                if (historyNode != null) {
+                    if (historyNode.isLatLonKnown()
+                            && changeset.getClosedAt().isAfter(historyNode.getInstant())) {
+                        n.load(historyNode.save());
+                        progressMonitor.worked(1);
+                    } else {
+                        versionMap.put(n.getId(), historyNode.getVersion());
+                    }
                 }
             }
Index: /applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java
===================================================================
--- /applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java	(revision 36236)
+++ /applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java	(revision 36237)
@@ -6,4 +6,5 @@
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.HttpURLConnection;
 import java.util.ArrayList;
 import java.util.List;
@@ -16,4 +17,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.io.OsmApiException;
 import org.openstreetmap.josm.io.OsmServerReader;
 import org.openstreetmap.josm.io.OsmTransferException;
@@ -50,5 +52,5 @@
      * @return The queries to make
      */
-    private static List<String> makeQueryStrings(OsmPrimitiveType type, Map<Long,Integer> list) {
+    private static List<String> makeQueryStrings(OsmPrimitiveType type, Map<Long, Integer> list) {
         // This is a "worst-case" calculation. Keep it fast (and err higher rather than lower), not accurate.
         final int expectedSize = (int) (list.entrySet().stream().mapToLong(entry ->
@@ -63,6 +65,6 @@
         List<String> result = new ArrayList<>(expectedSize + 1);
         StringBuilder sb = new StringBuilder();
-        int cnt=0;
-        for (Map.Entry<Long,Integer> entry : list.entrySet()) {
+        int cnt = 0;
+        for (Map.Entry<Long, Integer> entry : list.entrySet()) {
             if (cnt == 0) {
                 sb.append(type.getAPIName());
@@ -83,5 +85,5 @@
             }
         }
-        if (cnt>0) {
+        if (cnt > 0) {
             result.add(sb.toString());
         }
@@ -109,12 +111,12 @@
 
     /**
-     * Parse many objects
+     * Parse many objects.
      * @param type The object type (<i>must</i> be common between all objects)
-     * @param list The map of object id to object version
+     * @param list The map of object id to object version. Successfully retrieved objects are removed.
      * @param progressMonitor The progress monitor to update
      * @throws OsmTransferException If there is an issue getting the data
      */
-    public void readMultiObjects(OsmPrimitiveType type, Map<Long,Integer> list, ProgressMonitor progressMonitor) throws OsmTransferException {
-        for (String query : makeQueryStrings(type,list)) {
+    public void readMultiObjects(OsmPrimitiveType type, Map<Long, Integer> list, ProgressMonitor progressMonitor) throws OsmTransferException {
+        for (String query : makeQueryStrings(type, list)) {
             if (progressMonitor.isCanceled()) {
                 return;
@@ -130,7 +132,52 @@
                 Logging.warn(e);
                 throw new OsmTransferException(e);
+            } catch (OsmApiException e) {
+                Logging.warn(e);
+                // allow to continue further bulk requests
+                if (e.getResponseCode() != HttpURLConnection.HTTP_FORBIDDEN
+                        && e.getResponseCode() != HttpURLConnection.HTTP_NOT_FOUND) {
+                    throw e;
+                }
             } finally {
                 rdr.callback = null;
             }
+        }
+    }
+
+    /**
+     * Parse many objects. If redacted elements are requested the method tries to retrieve the next older version.
+     * @param type The object type (<i>must</i> be common between all objects)
+     * @param list The map of object id to object version. Successfully retrieved objects are removed.
+     * @param progressMonitor The progress monitor to update
+     * @throws OsmTransferException If there is an issue getting the data
+     */
+    public void readMultiObjectsOrNextOlder(OsmPrimitiveType type, Map<Long, Integer> list,
+            ProgressMonitor progressMonitor) throws OsmTransferException {
+        readMultiObjects(type, list, progressMonitor);
+        // If multi-read failed, retry with regular read
+        for (Map.Entry<Long, Integer> entry : list.entrySet()) {
+            if (progressMonitor.isCanceled()) return;
+            readObjectVersion(type, entry.getKey(), entry.getValue(), progressMonitor);
+        }
+    }
+
+    private void readObjectVersion(OsmPrimitiveType type, long id, int version, ProgressMonitor progressMonitor)
+            throws OsmTransferException {
+        boolean readOK = false;
+        while (!readOK && version >= 1) {
+            try {
+                readObject(id, version, type, progressMonitor.createSubTaskMonitor(1, true));
+                readOK = true;
+            } catch (OsmApiException e) {
+                if (e.getResponseCode() != HttpURLConnection.HTTP_FORBIDDEN) {
+                    throw e;
+                }
+                String message = "Version " + version + " of " + id + " is unauthorized";
+                Logging.info(version <= 1 ? message : message + ", requesting previous one");
+                version--;
+            }
+        }
+        if (!readOK) {
+            Logging.warn("Cannot retrieve any previous version of {1} {2}", type, id);
         }
     }
