diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h
index 48a56c019bb..4ed38a194e4 100644
--- a/ndb/include/kernel/ndb_limits.h
+++ b/ndb/include/kernel/ndb_limits.h
@@ -61,6 +61,7 @@
 #define MAX_FIXED_KEY_LENGTH_IN_WORDS 8
 #define MAX_KEY_SIZE_IN_WORDS 1023
 #define MAX_FRM_DATA_SIZE 6000
+#define MAX_NULL_BITS 4096
 
 #define MIN_ATTRBUF ((MAX_ATTRIBUTES_IN_TABLE/24) + 1)
 /*
diff --git a/ndb/include/kernel/signaldata/TupFrag.hpp b/ndb/include/kernel/signaldata/TupFrag.hpp
index c132b19c50a..fe543cd1004 100644
--- a/ndb/include/kernel/signaldata/TupFrag.hpp
+++ b/ndb/include/kernel/signaldata/TupFrag.hpp
@@ -145,7 +145,8 @@ public:
   STATIC_CONST( SignalLength = 2 );
   enum ErrorCode {
     NoError = 0,
-    InvalidCharset = 743
+    InvalidCharset = 743,
+    TooManyBitsUsed = 831
   };
 private:
   Uint32 userPtr;
diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp
index a88c48b4cb3..ade57a5ee57 100644
--- a/ndb/include/util/Bitmask.hpp
+++ b/ndb/include/util/Bitmask.hpp
@@ -818,7 +818,7 @@ BitmaskImpl::getField(unsigned size, const Uint32 src[],
   
   src += (pos >> 5);
   Uint32 offset = pos & 31;
-  dst[0] = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
+  * dst = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
   
   if(offset + len <= 32)
   {
diff --git a/ndb/src/common/util/Bitmask.cpp b/ndb/src/common/util/Bitmask.cpp
index 2499e016a13..4169434483f 100644
--- a/ndb/src/common/util/Bitmask.cpp
+++ b/ndb/src/common/util/Bitmask.cpp
@@ -23,9 +23,12 @@ BitmaskImpl::getFieldImpl(const Uint32 src[],
 			  unsigned shiftL, unsigned len, Uint32 dst[])
 {
   assert(shiftL < 32);
-  
+
   unsigned shiftR = 32 - shiftL;
   unsigned undefined = shiftL ? ~0 : 0;
+
+  * dst = shiftL ? * dst : 0;
+  
   while(len >= 32)
   {
     * dst++ |= (* src) << shiftL;
@@ -169,6 +172,69 @@ void simple(int pos, int size)
   require(cmp(src, dst, size+31));
 };
 
+static
+void simple2(int size, int loops)
+{
+  ndbout_c("simple2 %d - ", size);
+  Vector<Uint32> _mask;
+  Vector<Uint32> _src;
+  Vector<Uint32> _dst;
+
+  Uint32 sz32 = (size + 32) >> 5;
+  Uint32 sz = sz32 << 2;
+  
+  Uint32 zero = 0;
+  _mask.fill(sz32+1, zero);
+  _src.fill(sz32+1, zero);
+  _dst.fill(sz32+1, zero);
+
+  Uint32 * src = _src.getBase();
+  Uint32 * dst = _dst.getBase();
+  Uint32 * mask = _mask.getBase();
+
+  Vector<Uint32> save;
+  for(int i = 0; i<loops; i++)
+  {
+    memset(mask, 0xFF, sz);
+    memset(dst, 0xFF, sz);
+    int len;
+    int pos = 0;
+    while(pos+1 < size)
+    {
+      memset(src, 0xFF, sz);
+      while(!(len = rand() % (size - pos)));
+      BitmaskImpl::setField(sz32, mask, pos, len, src);
+      if(memcmp(dst, mask, sz))
+      {
+	ndbout_c("pos: %d len: %d", pos, len);
+	print(mask, size);
+	abort();
+      }
+      printf("[ %d %d ]", pos, len);
+      save.push_back(pos);
+      save.push_back(len);
+      pos += len;
+    }
+
+    for(int j = 0; j<save.size(); )
+    {
+      pos = save[j++];
+      len = save[j++];
+      memset(src, 0xFF, sz);
+      BitmaskImpl::getField(sz32, mask, pos, len, src);
+      if(memcmp(dst, src, sz))
+      {
+	ndbout_c("pos: %d len: %d", pos, len);
+	printf("src: "); print(src, size); printf("\n");
+	printf("dst: "); print(dst, size); printf("\n");
+	printf("msk: "); print(mask, size); printf("\n");
+	abort();
+      }
+    }
+    ndbout_c("");
+  }
+}
+
 static void 
 do_test(int bitmask_size)
 {
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
index 943f1ab02c4..56ae861270c 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
@@ -311,6 +311,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
     setTabDescrWord(firstTabDesIndex, attrDescriptor);
     Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
     Uint32 nullBitPos = fragOperPtr.p->currNullBit;
+    Uint32 bitCount = 0;
 
     if (AttributeDescriptor::getNullable(attrDescriptor)) {
       if (!AttributeDescriptor::getDynamic(attrDescriptor)) {
@@ -342,7 +343,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
 	else
 	{
 	  ljam();
-	  Uint32 bitCount = AttributeDescriptor::getArraySize(attrDescriptor);
+	  bitCount = AttributeDescriptor::getArraySize(attrDescriptor);
 	  fragOperPtr.p->currNullBit += bitCount;
 	  break;
 	}
@@ -351,6 +352,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
         ndbrequire(false);
         break;
       }//switch
+      if(nullBitPos + bitCount + 1 >= MAX_NULL_BITS)
+      {
+	terrorCode = TupAddAttrRef::TooManyBitsUsed;
+        addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
+	return;
+      }
       AttributeOffset::setOffset(attrDes2, attributePos);
       AttributeOffset::setNullFlagPos(attrDes2, nullBitPos);
     } else {
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index c0a6b6ba122..638996530e2 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -259,6 +259,7 @@ ErrorBundle ErrorCodes[] = {
    * Application error
    */
   { 823,  AE, "Too much attrinfo from application in tuple manager" },
+  { 831,  AE, "Too many nullable/bitfields in table definition" },
   { 876,  AE, "876" },
   { 877,  AE, "877" },
   { 878,  AE, "878" },
@@ -270,7 +271,7 @@ ErrorBundle ErrorCodes[] = {
   { 897,  AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" },
   { 4256, AE, "Must call Ndb::init() before this function" },
   { 4257, AE, "Tried to read too much - too many getValue calls" },
-
+  
   /** 
    * Scan application errors
    */
diff --git a/ndb/test/ndbapi/testBitfield.cpp b/ndb/test/ndbapi/testBitfield.cpp
index 1438f65418b..42439e20959 100644
--- a/ndb/test/ndbapi/testBitfield.cpp
+++ b/ndb/test/ndbapi/testBitfield.cpp
@@ -7,7 +7,7 @@
 
 static const char* opt_connect_str= 0;
 static const char* _dbname = "TEST_DB";
-static int g_loops = 5;
+static int g_loops = 7;
 static struct my_option my_long_options[] =
 {
   NDB_STD_OPTS("ndb_desc"),
@@ -130,44 +130,48 @@ static
 const NdbDictionary::Table* 
 create_random_table(Ndb* pNdb)
 {
-  NdbDictionary::Table tab;
-  Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
-  Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
-  Uint32 length = 4096;
-  Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS;
-  
-  BaseString name; 
-  name.assfmt("TAB_%d", rand() & 65535);
-  tab.setName(name.c_str());
-  for(int i = 0; i<cols && length > 0; i++)
-  {
-    NdbDictionary::Column col;
-    name.assfmt("COL_%d", i);
-    col.setName(name.c_str());
-    if(i == 0 || i == 1)
-    {
-      col.setType(NdbDictionary::Column::Unsigned);
-      col.setLength(1); 
-      col.setNullable(false);
-      col.setPrimaryKey(i == 0);
-      tab.addColumn(col);
-      continue;
-    }
-
-    col.setType(NdbDictionary::Column::Bit);
+  do {
+    NdbDictionary::Table tab;
+    Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
+    Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
+    Uint32 length = 4090;
+    Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS;
     
-    Uint32 len = 1 + (rand() % 128); //(length - 1));
-    col.setLength(len); length -= len;
-    col.setNullable((rand() >> 16) & 1);
-    col.setPrimaryKey(false);
-    tab.addColumn(col);
-  }
-
-  ndbout << (NDBT_Table&)tab << endl;
-  if(pNdb->getDictionary()->createTable(tab) == 0)
-  {
-    return pNdb->getDictionary()->getTable(tab.getName());
-  }
+    BaseString name; 
+    name.assfmt("TAB_%d", rand() & 65535);
+    tab.setName(name.c_str());
+    for(int i = 0; i<cols && length > 2; i++)
+    {
+      NdbDictionary::Column col;
+      name.assfmt("COL_%d", i);
+      col.setName(name.c_str());
+      if(i == 0 || i == 1)
+      {
+	col.setType(NdbDictionary::Column::Unsigned);
+	col.setLength(1); 
+	col.setNullable(false);
+	col.setPrimaryKey(i == 0);
+	tab.addColumn(col);
+	continue;
+      }
+      
+      col.setType(NdbDictionary::Column::Bit);
+      
+      Uint32 len = 1 + (rand() % (length - 1));
+      col.setLength(len); length -= len;
+      int nullable = (rand() >> 16) & 1;
+      col.setNullable(nullable); length -= nullable;
+      col.setPrimaryKey(false);
+      tab.addColumn(col);
+    }
+    
+    pNdb->getDictionary()->dropTable(tab.getName());
+    if(pNdb->getDictionary()->createTable(tab) == 0)
+    {
+      ndbout << (NDBT_Table&)tab << endl;
+      return pNdb->getDictionary()->getTable(tab.getName());
+    }
+  } while(0);
   return 0;
 }
 
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index 8a927b88194..dce89766319 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -506,6 +506,10 @@ max-time: 2500
 cmd: testOIBasic
 args: 
 
+max-time: 2500
+cmd: testBitfield
+args:
+
 #
 #
 # SYSTEM RESTARTS