diff --git a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java
index 07ad7ecc7bd156309c4492eb80fe521b2365a144..eecaeeff132509ba68157b02e4988d5ecce371be 100644
--- a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java
+++ b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java
@@ -82,6 +82,7 @@ public class ElGamalAESEngine {
         SessionKey usedKey = new SessionKey();
         Set foundTags = new HashSet();
         byte decrypted[] = null;
+        boolean wasExisting = false;
         if (key != null) {
             //if (_log.shouldLog(Log.DEBUG)) _log.debug("Key is known for tag " + st);
             usedKey.setData(key.getData());
@@ -94,10 +95,11 @@ public class ElGamalAESEngine {
                 _context.statManager().updateFrequency("crypto.elGamalAES.decryptExistingSession");
                 if ( (foundTags.size() > 0) && (_log.shouldLog(Log.WARN)) )
                     _log.warn(id + ": ElG/AES decrypt success with " + st + ": found tags: " + foundTags);
+                wasExisting = true;
             } else {
                 _context.statManager().updateFrequency("crypto.elGamalAES.decryptFailed");
-                if (_log.shouldLog(Log.ERROR)) {
-                    _log.error(id + ": ElG decrypt fail: known tag [" + st + "], failed decrypt");
+                if (_log.shouldLog(Log.WARN)) {
+                    _log.warn(id + ": ElG decrypt fail: known tag [" + st + "], failed decrypt");
                 }
             }
         } else {
@@ -109,8 +111,8 @@ public class ElGamalAESEngine {
                     _log.warn("ElG decrypt success: found tags: " + foundTags);
             } else {
                 _context.statManager().updateFrequency("crypto.elGamalAES.decryptFailed");
-                if (_log.shouldLog(Log.ERROR))
-                    _log.error("ElG decrypt fail: unknown tag: " + st);
+                if (_log.shouldLog(Log.WARN))
+                    _log.warn("ElG decrypt fail: unknown tag: " + st);
             }
         }
 
@@ -121,11 +123,11 @@ public class ElGamalAESEngine {
         if (foundTags.size() > 0) {
             if (foundKey.getData() != null) {
                 if (_log.shouldLog(Log.DEBUG)) 
-                    _log.debug("Found key: " + foundKey.toBase64() + " tags: " + foundTags);
+                    _log.debug("Found key: " + foundKey.toBase64() + " tags: " + foundTags + " wasExisting? " + wasExisting);
                 _context.sessionKeyManager().tagsReceived(foundKey, foundTags);
             } else {
                 if (_log.shouldLog(Log.DEBUG)) 
-                    _log.debug("Used key: " + usedKey.toBase64() + " tags: " + foundTags);
+                    _log.debug("Used key: " + usedKey.toBase64() + " tags: " + foundTags + " wasExisting? " + wasExisting);
                 _context.sessionKeyManager().tagsReceived(usedKey, foundTags);
             }
         }
diff --git a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java
index 33cf4e7d6e00016d52baa8e08489f034f60d7bc6..4a184f6bec7720a35f4bb82abe33614ba6b8e694 100644
--- a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java
+++ b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java
@@ -253,6 +253,7 @@ class TransientSessionKeyManager extends SessionKeyManager {
         int overage = 0;
         TagSet tagSet = new TagSet(sessionTags, key, _context.clock().now());
         TagSet old = null;
+        SessionTag dupTag = null;
         for (Iterator iter = sessionTags.iterator(); iter.hasNext();) {
             SessionTag tag = (SessionTag) iter.next();
             if (_log.shouldLog(Log.DEBUG))
@@ -263,6 +264,7 @@ class TransientSessionKeyManager extends SessionKeyManager {
                 if (old != null) {
                     if (!old.getAssociatedKey().equals(tagSet.getAssociatedKey())) {
                         _inboundTagSets.remove(tag);
+                        dupTag = tag;
                         break;
                     } else {
                         old = null; // ignore the dup
@@ -284,10 +286,10 @@ class TransientSessionKeyManager extends SessionKeyManager {
                 }
             }
 
-            if (_log.shouldLog(Log.WARN)) {
-                _log.warn("Multiple tags matching!  tagSet: " + tagSet + " and old tagSet: " + old);
-                _log.warn("Earlier tag set creation: " + old + ": key=" + old.getAssociatedKey().toBase64(), old.getCreatedBy());
-                _log.warn("Current tag set creation: " + tagSet + ": key=" + tagSet.getAssociatedKey().toBase64(), tagSet.getCreatedBy());
+            if (_log.shouldLog(Log.ERROR)) {
+                _log.error("Multiple tags matching!  tagSet: " + tagSet + " and old tagSet: " + old + " tag: " + dupTag);
+                _log.error("Earlier tag set creation: " + old + ": key=" + old.getAssociatedKey().toBase64(), old.getCreatedBy());
+                _log.error("Current tag set creation: " + tagSet + ": key=" + tagSet.getAssociatedKey().toBase64(), tagSet.getCreatedBy());
             }
         }
         
@@ -662,10 +664,12 @@ class TransientSessionKeyManager extends SessionKeyManager {
             _sessionTags = tags;
             _key = key;
             _date = date;
-            if (true) 
+            if (true) {
+                long now = I2PAppContext.getGlobalContext().clock().now();
                 _createdBy = new Exception("Created by: key=" + _key.toBase64() + " on " 
-                                           + new Date(I2PAppContext.getGlobalContext().clock().now()) 
+                                           + new Date(now) + "/" + now 
                                            + " via " + Thread.currentThread().getName());
+            }
         }
 
         /** when the tag set was created */
diff --git a/core/java/src/net/i2p/data/SessionTag.java b/core/java/src/net/i2p/data/SessionTag.java
index 5bbaaeda046e91a00be8dee6842ba5934410e338..9b5af9c738c67fb0d3714727d73e3d059bb0617c 100644
--- a/core/java/src/net/i2p/data/SessionTag.java
+++ b/core/java/src/net/i2p/data/SessionTag.java
@@ -41,6 +41,7 @@ public class SessionTag extends ByteArray {
         if (val.length != BYTE_LENGTH)
             throw new IllegalArgumentException("SessionTags must be " + BYTE_LENGTH + " bytes");
         super.setData(val);
+        setValid(BYTE_LENGTH);
     }
 
     public void readBytes(InputStream in) throws DataFormatException, IOException {
diff --git a/history.txt b/history.txt
index c762e1a1e536774e7ace2e320b30c4063ccf1cc1..9b7869876cec8941eaa58f4c407ee462e5ca0277 100644
--- a/history.txt
+++ b/history.txt
@@ -1,8 +1,13 @@
-$Id: history.txt,v 1.209 2005/07/11 18:06:23 jrandom Exp $
+$Id: history.txt,v 1.210 2005/07/12 16:26:07 jrandom Exp $
+
+2005-07-13  jrandom
+    * Fixed a long standing bug where we weren't properly comparing session 
+      tags but instead largely depending upon comparing their hashCode, 
+      causing intermittent decryption errors.
 
 2005-07-12  jrandom
-    * Add some data duplication to avoid a recently injected concurrency problem 
-      in the session tag manager (thanks redzara and romster).
+    * Add some data duplication to avoid a recently injected concurrency 
+      problem in the session tag manager (thanks redzara and romster).
 
 2005-07-11  jrandom
     * Reduced the growth factor on the slow start and congestion avoidance for
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 626bef3aeab8ed442a5bfcb4c571b7884e8fe23b..a6489226fe952c59b91dd7a60a0d5369de32475c 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
  *
  */
 public class RouterVersion {
-    public final static String ID = "$Revision: 1.200 $ $Date: 2005/07/11 18:06:24 $";
+    public final static String ID = "$Revision: 1.201 $ $Date: 2005/07/12 16:26:07 $";
     public final static String VERSION = "0.5.0.7";
-    public final static long BUILD = 12;
+    public final static long BUILD = 13;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + VERSION);
         System.out.println("Router ID: " + RouterVersion.ID);