diff --git a/history.txt b/history.txt
index 450c4b5c4388e826d9a7f4a6b0ca567acf22b869..d362df86813ad7c2ce73d4fc537f51eb17ab7b62 100644
--- a/history.txt
+++ b/history.txt
@@ -4,6 +4,15 @@
  * Arabic, Chinese, Czech, Dutch, French, German, Russian, and Spanish
    translation updates from Transifex
 
+2014-10-30 zzz
+ * Router: Fix rare NPE building garlic message (ticket #1403)
+
+2014-10-26 zzz
+ * SSU: Fix ACK Sender thread dying on corrupt packet
+
+2014-10-24 zzz
+ * i2ptunnel: Fix description entered via wizard
+
 2014-10-23 zzz
  * SessionKeyManager:
    - Raise inbound limit
@@ -539,7 +548,7 @@ Prop from i2p.i2p.zzz.test2:
 
 2014-05-15 kytv
  * Translations, imported from Transifex:
-   - Dutch, French, German, Italian, Japanese, Norwegian Bokmål, and Ukrainian
+   - Dutch, French, German, Italian, Japanese, Norwegian Bokml, and Ukrainian
      translation updates
    - Start of Slovak language translation
  * Updates to geoip.txt and geoipv6.dat.gz based on Maxmind GeoLite Country
@@ -2106,7 +2115,7 @@ i2psnark: Fix ConnectionAcceptor not restarting after tunnel
    transifex.
 
 2013-02-13 kytv
- * Flag for Curaçao (CW), public domain
+ * Flag for Curaao (CW), public domain
 
 2013-02-12 zzz
  * NetDB: Randomize delay before floodfill store verify
@@ -2133,8 +2142,8 @@ i2psnark: Fix ConnectionAcceptor not restarting after tunnel
      - Allow any domain name to be mapped, not just .i2p
 
 2013-01-31 kytv
- * Add Norwegian Bokmål language to the router console
- * Add Bokmål translations from Transifex
+ * Add Norwegian Bokml language to the router console
+ * Add Bokml translations from Transifex
 
 2013-01-31 zzz
  * EepGet:
@@ -5023,7 +5032,7 @@ i2psnark: Fix ConnectionAcceptor not restarting after tunnel
     * Reseed: Log tweak
 
 2011-04-02 m1xxy
-    * routerconsole, i2psnark, ...  I2P ahora también en español: ¡Bienvenidos los hispanohablantes!
+    * routerconsole, i2psnark, ...  I2P ahora tambin en espaol: Bienvenidos los hispanohablantes!
       - routerconsole, i2ptunnel, i2psnark, SusiDNS, Susimail fully translated into Spanish
         (thx to PunkiBastardo and user)
     * routerconsole, i2psnark, ...
@@ -7165,7 +7174,7 @@ i2psnark: Fix ConnectionAcceptor not restarting after tunnel
       - Java 5 cleanups
     * Console:
       - Put favicon on every page
-      - Make every page UTF-8, ☃ safe for snowmen
+      - Make every page UTF-8,  safe for snowmen
       - Remove options boxes on configtunnels.jsp
       - Fix UTF-8 form submission (i2ptunnel too)
       - Throw 403 instead of 404 from flags.jsp and viewstat.jsp
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 25340f779d31df7c3f3df56d3d62b65ed0ca042b..098e16d499456339b4699536706ff45ebf0c4769 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -18,7 +18,7 @@ public class RouterVersion {
     /** deprecated */
     public final static String ID = "Monotone";
     public final static String VERSION = CoreVersion.VERSION;
-    public final static long BUILD = 15;
+    public final static long BUILD = 17;
 
     /** for example "-test" */
     public final static String EXTRA = "-rc";
diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java b/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java
index 08c001e222da93b05fc9c20b7f4c482252bb26aa..bb7cb83a87190660a9a488cebfd529ecb760ee93 100644
--- a/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java
+++ b/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java
@@ -220,6 +220,11 @@ class OutboundClientMessageJobHelper {
         ackClove.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
         DeliveryStatusMessage dsm = buildDSM(ctx, replyToken);
         GarlicMessage msg = wrapDSM(ctx, skm, dsm);
+        if (msg == null) {
+            if (log.shouldLog(Log.WARN))
+                log.warn("Failed to wrap ack clove");
+            return null;
+        }
         ackClove.setPayload(msg);
         // this does nothing, the clove is not separately encrypted
         //ackClove.setRecipient(ctx.router().getRouterInfo());
diff --git a/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
index fcaae36dd05f10a1ac301e6466f42f358e3f4da9..8c20dba177f527b7f23a1bc88267f37f2e578334 100644
--- a/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
+++ b/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
@@ -72,10 +72,14 @@ class InboundMessageState implements CDQEntry {
         _log = ctx.logManager().getLog(InboundMessageState.class);
         _messageId = messageId;
         _from = from;
-        if (data.readMessageIsLast(dataFragment))
-            _fragments = new ByteArray[1 + data.readMessageFragmentNum(dataFragment)];
-        else
+        if (data.readMessageIsLast(dataFragment)) {
+            int num = 1 + data.readMessageFragmentNum(dataFragment);
+            if (num > MAX_FRAGMENTS)
+                throw new DataFormatException("corrupt - too many fragments: " + num);
+            _fragments = new ByteArray[num];
+        } else {
             _fragments = new ByteArray[MAX_FRAGMENTS];
+        }
         _lastFragment = -1;
         _completeSize = -1;
         _receiveBegin = ctx.clock().now();
@@ -222,8 +226,10 @@ class InboundMessageState implements CDQEntry {
         return _completeSize;
     }
 
+    /** FIXME synch here or PeerState.fetchPartialACKs() */
     public ACKBitfield createACKBitfield() {
-        int sz = (_lastFragment >= 0) ? _lastFragment + 1 : _fragments.length;
+        int last = _lastFragment;
+        int sz = (last >= 0) ? last + 1 : _fragments.length;
         return new PartialBitfield(_messageId, _fragments, sz);
     }