diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java
index 45153c6c9aa3bd1a1dd7b104a73a9e9a39446c44..3287dc7c4a3d67b25ecdd16e45f6972f7cf1aa93 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.TreeSet;
 
 import net.i2p.crypto.SigType;
+import net.i2p.data.DatabaseEntry;
 import net.i2p.data.DataHelper;
 import net.i2p.data.Destination;
 import net.i2p.data.Hash;
@@ -517,6 +518,7 @@ class NetDbRenderer {
                         median = dist;
                 }
                 buf.append("&nbsp;&nbsp;<b>Distance: </b>").append(fmt.format(biLog2(dist)));
+                buf.append("&nbsp;&nbsp;<b>Type: </b>").append(ls.getType());
                 buf.append("</td></tr>\n<tr><td colspan=\"2\">");
                 //buf.append(dest.toBase32()).append("<br>");
                 buf.append("<b>Signature type:</b> ").append(dest.getSigningPublicKey().getType());
@@ -527,14 +529,18 @@ class NetDbRenderer {
 
             }
             buf.append("<tr><td colspan=\"2\"><ul class=\"netdb_leases\">");
+            boolean isMeta = ls.getType() == DatabaseEntry.KEY_TYPE_META_LS2;
             for (int i = 0; i < ls.getLeaseCount(); i++) {
                 Lease lease = ls.getLease(i);
                 buf.append("<li><b>").append(_t("Lease")).append(' ').append(i + 1).append(":</b> <span class=\"netdb_gateway\" title=\"")
                    .append(_t("Gateway")).append("\"><img src=\"themes/console/images/info/gateway.png\" alt=\"")
                    .append(_t("Gateway")).append("\"></span> <span class=\"tunnel_peer\">");
                 buf.append(_context.commSystem().renderPeerHTML(lease.getGateway()));
-                buf.append("</span> <span class=\"netdb_tunnel\">").append(_t("Tunnel")).append(" <span class=\"tunnel_id\">")
-                   .append(lease.getTunnelId().getTunnelId()).append("</span></span> ");
+                buf.append("</span> ");
+                if (!isMeta) {
+                    buf.append("<span class=\"netdb_tunnel\">").append(_t("Tunnel")).append(" <span class=\"tunnel_id\">")
+                       .append(lease.getTunnelId().getTunnelId()).append("</span></span> ");
+                }
                 if (debug) {
                     long exl = lease.getEndDate().getTime() - now;
                     if (exl > 0)
diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java
index 24f52347ddd71af1eb12db921e783f44fead7980..d03ef2fa7f37c7674beb146e45b87037eda848a5 100644
--- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java
+++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java
@@ -11,6 +11,7 @@ import net.i2p.client.SendMessageOptions;
 import net.i2p.crypto.SessionKeyManager;
 import net.i2p.crypto.TagSetHandle;
 import net.i2p.data.Certificate;
+import net.i2p.data.DatabaseEntry;
 import net.i2p.data.DataHelper;
 import net.i2p.data.Destination;
 import net.i2p.data.Hash;
@@ -271,6 +272,12 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
             dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_EXPIRED);
             return;
         }
+        if (_leaseSet != null && _leaseSet.getType() == DatabaseEntry.KEY_TYPE_META_LS2) {
+            // can't send to a meta LS
+            dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_BAD_LEASESET);
+            return;
+        }
+
         //if (_log.shouldLog(Log.DEBUG))
         //    _log.debug(getJobId() + ": Send outbound client message job beginning" +
         //               ": preparing to search for the leaseSet for " + _toString);
@@ -352,14 +359,14 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
                 getContext().statManager().addRateData("client.leaseSetFoundRemoteTime", lookupTime);
             }
             _wantACK = false;
-            boolean ok = getNextLease();
-            if (ok) {
+            int rc = getNextLease();
+            if (rc == 0) {
                 send();
             } else {
                 // shouldn't happen
                 if (_log.shouldLog(Log.WARN))
                     _log.warn("Unable to send on a random lease, as getNext returned null (to=" + _toString + ")");
-                dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_LEASESET);
+                dieFatal(rc);
             }
         }
     }
@@ -367,9 +374,9 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
     /**
      *  Choose a lease from his leaseset to send the message to. Sets _lease.
      *  Sets _wantACK if it's new or changed.
-     *  @return success
+     *  @return 0 on success, or a MessageStatusMessage failure code
      */
-    private boolean getNextLease() {
+    private int getNextLease() {
         // set in runJob if found locally
         if (_leaseSet == null) {
             _leaseSet = getContext().netDb().lookupLeaseSetLocally(_to.calculateHash());
@@ -377,9 +384,13 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
                 // shouldn't happen
                 if (_log.shouldLog(Log.WARN))
                     _log.warn(getJobId() + ": Lookup locally didn't find the leaseSet for " + _toString);
-                return false;
+                return MessageStatusMessage.STATUS_SEND_FAILURE_NO_LEASESET;
             } 
         } 
+        if (_leaseSet.getType() == DatabaseEntry.KEY_TYPE_META_LS2) {
+            // can't send to a meta LS
+            return MessageStatusMessage.STATUS_SEND_FAILURE_BAD_LEASESET;
+        }
 
         // Use the same lease if it's still good
         // Even if _leaseSet changed, _leaseSet.getEncryptionKey() didn't...
@@ -398,7 +409,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
                             _lease.getGateway().equals(lease.getGateway())) {
                             if (_log.shouldLog(Log.INFO))
                                 _log.info(getJobId() + ": Found in cache - lease for " + _toString); 
-                            return true;
+                            return 0;
                         }
                     }
                 }
@@ -431,7 +442,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
         if (leases.isEmpty()) {
             if (_log.shouldLog(Log.INFO))
                 _log.info(getJobId() + ": No leases found from: " + _leaseSet);
-            return false;
+            return MessageStatusMessage.STATUS_SEND_FAILURE_BAD_LEASESET;
         }
         
         // randomize the ordering (so leases with equal # of failures per next 
@@ -484,7 +495,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
         if (_log.shouldLog(Log.INFO))
             _log.info(getJobId() + ": Added to cache - lease for " + _toString); 
         _wantACK = true;
-        return true;
+        return 0;
     }
 
     
@@ -590,6 +601,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
         if (wantACK) {
             _cache.lastReplyRequestCache.put(_hashPair, Long.valueOf(now));
             token = getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
+            // 0.9.38 change to DESTINATION reply delivery
+            // NOPE! Rejected in InboundMessageDistributor
             _inTunnel = selectInboundTunnel();
         } else {
             token = -1;