Index: lucene/src/java/org/apache/lucene/index/SegmentReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentReader.java	(revision 1124266)
+++ lucene/src/java/org/apache/lucene/index/SegmentReader.java	(working copy)
@@ -38,6 +38,7 @@
 import org.apache.lucene.store.IndexOutput;
 import org.apache.lucene.util.BitVector;
 import org.apache.lucene.util.CloseableThreadLocal;
+import org.apache.lucene.util.StringHelper;
 
 /**
  * @lucene.experimental
@@ -530,6 +531,7 @@
       boolean success = false;
       try {
         try {
+          out.writeBytes(SegmentMerger.NORMS_HEADER, 0, SegmentMerger.NORMS_HEADER.length);
           out.writeBytes(bytes, maxDoc());
         } finally {
           out.close();
@@ -1124,8 +1126,20 @@
           // If this were to change in the future, a clone could be done here.
           normInput = singleNormStream;
         } else {
-          normSeek = 0;
           normInput = d.openInput(fileName);
+          // if the segment was created in 3.2 or after, we wrote the header for sure,
+          // and don't need to do the sketchy file size check. otherwise, we check 
+          // if the size is exactly equal to maxDoc to detect a headerless file.
+          // NOTE: remove this check in Lucene 5.0!
+          String version = si.getVersion();
+          final boolean isUnversioned = 
+            (version == null || StringHelper.getVersionComparator().compare(version, "3.2") < 0)
+            && normInput.length() == maxDoc();
+          if (isUnversioned) {
+            normSeek = 0;
+          } else {
+            normSeek = SegmentMerger.NORMS_HEADER.length;
+          }
         }
 
         norms.put(fi.name, new Norm(normInput, fi.number, normSeek));
