diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java
index fdf7f7ee99e18ba4c4fe5439f1ca20f238a747a5..78144891cccd1b0b71818716213e92fe24806d13 100644
--- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java
+++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java
@@ -249,6 +249,14 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
         if (_receivedUnconfirmedIdentity != null)
             throw new DataFormatException("DUP RI in Sess Conf");
         _receivedUnconfirmedIdentity = ri.getIdentity();
+        if (ri.getPublished() < 0) {
+            // see SSU2Payload: RI format error, signature was verified there, so we can take action
+            _context.blocklist().add(_aliceIP);
+            Hash h = _receivedUnconfirmedIdentity.calculateHash();
+            _context.banlist().banlistRouter(h, "Signed bad RI", null,
+                                             null, _context.clock().now() + 4*24*60*60*1000);
+            throw new RIException("RI DFE " + h.toBase64(), REASON_BANNED);
+        }
 
         // try to find the right address, because we need the MTU
         boolean isIPv6 = _aliceIP.length == 16;
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState2.java b/router/java/src/net/i2p/router/transport/udp/PeerState2.java
index 033b4f4505de24d1f2d72aac1fe5e3dfdff5c35a..91916e8761be2c5cceff00d22dbd0e542324c0c7 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState2.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState2.java
@@ -657,6 +657,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
     public void gotRI(RouterInfo ri, boolean isHandshake, boolean flood) throws DataFormatException {
         if (_log.shouldDebug())
             _log.debug("Got RI in data phase " + ri + "\non: " + this);
+        if (ri.getPublished() < 0)
+            throw new DataFormatException("RI DFE " + ri.getIdentity().calculateHash().toBase64());
         try {
             Hash h = ri.getHash();
             if (h.equals(_context.routerHash()))
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java
index 797ec709de3c462d2647dce1ebd64a9044b56635..e0d319292ccc1b79c766e5a1f0bdf3e6c0085763 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java
@@ -1913,6 +1913,11 @@ class PeerTestManager {
         public void gotOptions(byte[] options, boolean isHandshake) {}
 
         public void gotRI(RouterInfo ri, boolean isHandshake, boolean flood) {
+            if (ri.getPublished() < 0) {
+                if (_log.shouldWarn())
+                    _log.warn("RI DFE " + ri.getIdentity().calculateHash().toBase64());
+                return;
+            }
             try {
                 Hash h = ri.getHash();
                 if (h.equals(_context.routerHash()))
diff --git a/router/java/src/net/i2p/router/transport/udp/SSU2Payload.java b/router/java/src/net/i2p/router/transport/udp/SSU2Payload.java
index cfe0d8416df38638a7edc45058311ca9878684a2..6c37d9f924bd20ced51159fc938fd4c98f562810 100644
--- a/router/java/src/net/i2p/router/transport/udp/SSU2Payload.java
+++ b/router/java/src/net/i2p/router/transport/udp/SSU2Payload.java
@@ -6,12 +6,17 @@ import java.util.Arrays;
 import java.util.List;
 
 import net.i2p.I2PAppContext;
+import net.i2p.crypto.DSAEngine;
+import net.i2p.crypto.SigType;
 import net.i2p.data.DataFormatException;
 import net.i2p.data.DataHelper;
 import net.i2p.data.Hash;
+import net.i2p.data.Signature;
+import net.i2p.data.SigningPublicKey;
 import net.i2p.data.i2np.I2NPMessage;
 import net.i2p.data.i2np.I2NPMessageException;
 import net.i2p.data.i2np.I2NPMessageImpl;
+import net.i2p.data.router.RouterIdentity;
 import net.i2p.data.router.RouterInfo;
 import net.i2p.util.Log;
 
@@ -211,7 +216,36 @@ class SSU2Payload {
                         if (bais.available() >= 3*1024)
                             flood = false;
                         RouterInfo alice = new RouterInfo();
-                        alice.readBytes(bais, true);
+                        try {
+                            alice.readBytes(bais, true);
+                        } catch (DataFormatException dfe) {
+                            // alternate verify of signature.
+                            // if a badly formatted RI was correctly signed, we do a special callback
+                            bais.reset();
+                            RouterIdentity ident = new RouterIdentity();
+                            ident.readBytes(bais);
+                            SigningPublicKey pub = ident.getSigningPublicKey();
+                            SigType st = pub.getType();
+                            if (st == null)
+                                throw dfe;
+                            bais.reset();
+                            byte[] data = new byte[bais.available() - st.getSigLen()];
+                            bais.read(data);
+                            Signature sig = new Signature(st);
+                            sig.readBytes(bais);
+                            if (DSAEngine.getInstance().verifySignature(sig, data, pub)) {
+                                Log log = ctx.logManager().getLog(SSU2Payload.class);
+                                if (log.shouldWarn())
+                                    log.warn("Error reading RI", dfe);
+                                // partially filled-in RI, -1 is signal to IES2.gotRI()
+                                alice = new RouterInfo();
+                                alice.setIdentity(ident);
+                                alice.setPublished(-1);
+                            } else {
+                                // bad sig, just throw dfe
+                                throw dfe;
+                            }
+                        }
                         cb.gotRI(alice, isHandshake, flood);
                     } else {
                         byte[] data = new byte[len - 2];