Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java	(revision 17611)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java	(revision 17612)
@@ -41,12 +41,21 @@
 public class DuplicateNode extends Test {
 
-    private static class NodeHash implements Hash<Object, Object> {
-
-        private final double precision = Config.getPref().getDouble("validator.duplicatenodes.precision", 0.);
-
-        private LatLon roundCoord(LatLon coor) {
+    protected static class NodeHash implements Hash<Object, Object> {
+
+        /**
+         * Rounding on OSM server and via {@link LatLon#roundToOsmPrecision} sometimes differs in the last digit by 1.
+         * Thus, for the duplicate node test, we reduce the precision by one to find errors before uploading.
+         * @see LatLon#MAX_SERVER_INV_PRECISION
+         */
+        private final double precision =
+                1 / Config.getPref().getDouble("validator.duplicatenodes.precision", LatLon.MAX_SERVER_PRECISION * 10);
+
+        /**
+         * @see LatLon#roundToOsmPrecision
+         */
+        protected LatLon roundCoord(LatLon coor) {
             return new LatLon(
-                    Math.round(coor.lat() / precision) * precision,
-                    Math.round(coor.lon() / precision) * precision
+                    Math.round(coor.lat() * precision) / precision,
+                    Math.round(coor.lon() * precision) / precision
                     );
         }
Index: /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/DuplicateNodeTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/DuplicateNodeTest.java	(revision 17611)
+++ /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/DuplicateNodeTest.java	(revision 17612)
@@ -178,4 +178,30 @@
 
     /**
+     * Test of "Duplicate node" validation test - server precision.
+     *
+     * Non-regression test for ticket #18074.
+     */
+    @Test
+    void testServerPrecision() {
+        DuplicateNode.NodeHash nodeHash = new DuplicateNode.NodeHash();
+        DataSet ds = new DataSet();
+
+        Node a = new Node(new LatLon(-23.51108285, -46.489264256));
+        Node b = new Node(new LatLon(-23.511082861, -46.489264251));
+        ds.addPrimitive(a);
+        ds.addPrimitive(b);
+
+        a.put("foo", "bar");
+        b.put("bar", "foo");
+
+        // on OSM server, both are: lat = -23.5110829 lon = -46.4892643
+        assertEquals(new LatLon(-23.5110828, -46.4892643), a.getCoor().getRoundedToOsmPrecision());
+        assertEquals(new LatLon(-23.5110829, -46.4892643), b.getCoor().getRoundedToOsmPrecision());
+        assertEquals(new LatLon(-23.511083, -46.489264), nodeHash.roundCoord(a.getCoor()));
+        assertEquals(new LatLon(-23.511083, -46.489264), nodeHash.roundCoord(b.getCoor()));
+        performTest(DuplicateNode.DUPLICATE_NODE, ds, false);
+    }
+
+    /**
      * Test of "Duplicate node" validation test - mixed case.
      */
