diff --git a/cs/src/Ice/BasicStream.cs b/cs/src/Ice/BasicStream.cs
index 1201c21..690638d 100644
--- a/cs/src/Ice/BasicStream.cs
+++ b/cs/src/Ice/BasicStream.cs
@@ -136,7 +136,7 @@ namespace IceInternal
             _unlimited = unlimited;
 
             _startSeq = -1;
-            _sizePos = -1;
+            _sizeStack = null;
         }
 
         //
@@ -223,9 +223,9 @@ namespace IceInternal
             other._minSeqSize = _minSeqSize;
             _minSeqSize = tmpMinSeqSize;
 
-            int tmpSizePos = other._sizePos;
-            other._sizePos = _sizePos;
-            _sizePos = tmpSizePos;
+            Stack<int> tmpSizeStack = other._sizeStack;
+            other._sizeStack = _sizeStack;
+            _sizeStack = tmpSizeStack;
         }
 
         public void resetEncaps()
@@ -733,15 +733,19 @@ namespace IceInternal
 
         public void startSize()
         {
-            _sizePos = _buf.b.position();
+            if(_sizeStack == null)
+            {
+                _sizeStack = new Stack<int>();
+            }
+            _sizeStack.Push(_buf.b.position());
             writeInt(0); // Placeholder for 32-bit size
         }
 
         public void endSize()
         {
-            Debug.Assert(_sizePos >= 0);
-            rewriteInt(_buf.b.position() - _sizePos - 4, _sizePos);
-            _sizePos = -1;
+            Debug.Assert(_sizeStack.Count > 0);
+            int sizePos = _sizeStack.Pop();
+            rewriteInt(_buf.b.position() - sizePos - 4, sizePos);
         }
 
         public void writeBlob(byte[] v)
@@ -3582,6 +3586,7 @@ namespace IceInternal
         private Buffer _buf;
         private object _closure;
         private byte[] _stringBytes; // Reusable array for reading strings.
+        private Stack<int> _sizeStack;
 
         private enum SliceType { NoSlice, ObjectSlice, ExceptionSlice }
 
@@ -5410,8 +5415,6 @@ namespace IceInternal
         private int _startSeq;
         private int _minSeqSize;
 
-        private int _sizePos;
-
         private const byte OPTIONAL_END_MARKER           = 0xFF;
 
         private const byte FLAG_HAS_TYPE_ID_STRING       = (byte)(1<<0);
diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java
index b241147..c5bcbf5 100644
--- a/java/src/IceInternal/BasicStream.java
+++ b/java/src/IceInternal/BasicStream.java
@@ -62,7 +62,7 @@ public class BasicStream
         _unlimited = unlimited;
 
         _startSeq = -1;
-        _sizePos = -1;
+        _sizeStack = null;
     }
 
     //
@@ -155,9 +155,9 @@ public class BasicStream
         other._minSeqSize = _minSeqSize;
         _minSeqSize = tmpMinSeqSize;
 
-        int tmpSizePos = other._sizePos;
-        other._sizePos = _sizePos;
-        _sizePos = tmpSizePos;
+        java.util.Deque<Integer> tmpSizeStack = other._sizeStack;
+        other._sizeStack = _sizeStack;
+        _sizeStack = tmpSizeStack;
     }
 
     public void
@@ -715,16 +715,20 @@ public class BasicStream
     public void
     startSize()
     {
-        _sizePos = _buf.b.position();
+        if(_sizeStack == null)
+        {
+            _sizeStack = new java.util.ArrayDeque<Integer>();
+        }
+        _sizeStack.push(_buf.b.position());
         writeInt(0); // Placeholder for 32-bit size
     }
 
     public void
     endSize()
     {
-        assert(_sizePos >= 0);
-        rewriteInt(_buf.b.position() - _sizePos - 4, _sizePos);
-        _sizePos = -1;
+        assert(!_sizeStack.isEmpty());
+        int sizePos = _sizeStack.pop();
+        rewriteInt(_buf.b.position() - sizePos - 4, sizePos);
     }
 
     public void
@@ -2779,6 +2783,7 @@ public class BasicStream
     private Object _closure;
     private byte[] _stringBytes; // Reusable array for reading strings.
     private char[] _stringChars; // Reusable array for reading strings.
+    private java.util.Deque<Integer> _sizeStack;
 
     private enum SliceType { NoSlice, ObjectSlice, ExceptionSlice }
 
@@ -4618,8 +4623,6 @@ public class BasicStream
     private int _startSeq;
     private int _minSeqSize;
 
-    private int _sizePos;
-
     private static final int OPTIONAL_END_MARKER            = 0xFF;
 
     private static final byte FLAG_HAS_TYPE_ID_STRING       = (byte)(1<<0);
diff --git a/py/modules/IcePy/Types.cpp b/py/modules/IcePy/Types.cpp
index 85fec02..347e5f7 100644
--- a/py/modules/IcePy/Types.cpp
+++ b/py/modules/IcePy/Types.cpp
@@ -1232,11 +1232,15 @@ IcePy::StructInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMa
 {
     assert(PyObject_IsInstance(p, pythonType.get()) == 1); // validate() should have caught this.
 
+    int sizePos = -1;
     if(optional)
     {
         if(_variableLength)
         {
-            os->startSize();
+            // BUGFIX: #5481 startSize/endSize can't be nested
+            //os->startSize();
+            sizePos = os->pos();
+            os->write(Ice::Int(0));
         }
         else
         {
@@ -1266,7 +1270,9 @@ IcePy::StructInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMa
 
     if(optional && _variableLength)
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
@@ -1402,11 +1408,15 @@ IcePy::SequenceInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, Object
 {
     PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType);
 
+    int sizePos = -1;
     if(optional)
     {
         if(elementType->variableLength())
         {
-            os->startSize();
+            // BUGFIX: #5481 startSize/endSize can't be nested
+            //os->startSize();
+            sizePos = os->pos();
+            os->write(Ice::Int(0));
         }
         else if(elementType->wireSize() > 1)
         {
@@ -1490,7 +1500,9 @@ IcePy::SequenceInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, Object
 
     if(optional && elementType->variableLength())
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
@@ -2480,11 +2492,15 @@ IcePy::DictionaryInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, Obje
 
     const Ice::Int sz = p == Py_None ? 0 : static_cast<Ice::Int>(PyDict_Size(p));
 
+    int sizePos = -1;
     if(optional)
     {
         if(_variableLength)
         {
-            os->startSize();
+            // BUGFIX: #5481 startSize/endSize can't be nested
+            //os->startSize();
+            sizePos = os->pos();
+            os->write(Ice::Int(0));
         }
         else
         {
@@ -2523,7 +2539,9 @@ IcePy::DictionaryInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, Obje
 
     if(optional && _variableLength)
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
@@ -2958,9 +2976,13 @@ IcePy::ProxyInfo::optionalFormat() const
 void
 IcePy::ProxyInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional, const Ice::StringSeq*)
 {
+    int sizePos = -1;
     if(optional)
     {
-        os->startSize();
+        // BUGFIX: #5481 startSize/endSize can't be nested
+        //os->startSize();
+        sizePos = os->pos();
+        os->write(Ice::Int(0));
     }
 
     if(p == Py_None)
@@ -2978,7 +3000,9 @@ IcePy::ProxyInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap
 
     if(optional)
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
diff --git a/rb/src/IceRuby/Types.cpp b/rb/src/IceRuby/Types.cpp
index c4360f3..c52d12a 100644
--- a/rb/src/IceRuby/Types.cpp
+++ b/rb/src/IceRuby/Types.cpp
@@ -992,11 +992,15 @@ IceRuby::StructInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*
 {
     assert(callRuby(rb_obj_is_kind_of, p, rubyClass) == Qtrue); // validate() should have caught this.
 
+    int sizePos = -1;
     if(optional)
     {
         if(_variableLength)
         {
-            os->startSize();
+            // BUGFIX: #5481 startSize/endSize can't be nested
+            //os->startSize();
+            sizePos = os->pos();
+            os->write(Ice::Int(0));
         }
         else
         {
@@ -1018,7 +1022,9 @@ IceRuby::StructInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*
 
     if(optional && _variableLength)
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
@@ -1153,11 +1159,15 @@ IceRuby::SequenceInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMa
 
     volatile VALUE arr = Qnil;
 
+    int sizePos = -1;
     if(optional)
     {
         if(elementType->variableLength())
         {
-            os->startSize();
+            // BUGFIX: #5481 startSize/endSize can't be nested
+            //os->startSize();
+            sizePos = os->pos();
+            os->write(Ice::Int(0));
         }
         else if(elementType->wireSize() > 1)
         {
@@ -1219,7 +1229,9 @@ IceRuby::SequenceInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMa
 
     if(optional && elementType->variableLength())
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
@@ -1372,7 +1384,7 @@ IceRuby::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, VALU
             const long len = RSTRING_LEN(str);
             if(s == 0 || len == 0)
             {
-                os->writeSize(0);
+                os->write(Ice::Int(0));
             }
             else
             {
@@ -1721,11 +1733,15 @@ IceRuby::DictionaryInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, Object
         sz = RHASH_SIZE(hash);
     }
 
+    int sizePos = -1;
     if(optional)
     {
         if(_variableLength)
         {
-            os->startSize();
+            // BUGFIX: #5481 startSize/endSize can't be nested
+            //os->startSize();
+            sizePos = os->pos();
+            os->write(Ice::Int(0));
         }
         else
         {
@@ -1749,7 +1765,9 @@ IceRuby::DictionaryInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, Object
 
     if(optional && _variableLength)
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
@@ -2301,9 +2319,13 @@ IceRuby::ProxyInfo::optionalFormat() const
 void
 IceRuby::ProxyInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional)
 {
+    int sizePos = -1;
     if(optional)
     {
-        os->startSize();
+        // BUGFIX: #5481 startSize/endSize can't be nested
+        //os->startSize();
+        sizePos = os->pos();
+        os->write(Ice::Int(0));
     }
 
     if(NIL_P(p))
@@ -2318,7 +2340,9 @@ IceRuby::ProxyInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectMap*,
 
     if(optional)
     {
-        os->endSize();
+        assert(sizePos != -1);
+        //os->endSize();
+        os->rewrite(os->pos() - sizePos - 4, sizePos);
     }
 }
 
