diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 090fa67b79a..b1b5e081a80 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -27,6 +27,7 @@ export encode_metadata;
 export encoded_ty;
 export reachable;
 export encode_inlined_item;
+export metadata_encoding_version;
 
 // used by astencode:
 export def_to_str;
@@ -1084,6 +1085,13 @@ fn encode_hash(ebml_w: ebml::Writer, hash: ~str) {
     ebml_w.end_tag();
 }
 
+// NB: Increment this as you change the metadata encoding version.
+const metadata_encoding_version : &[u8] = &[0x72, //'r' as u8,
+                                            0x75, //'u' as u8,
+                                            0x73, //'s' as u8,
+                                            0x74, //'t' as u8,
+                                            0, 0, 0, 1 ];
+
 fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
     let buf = io::mem_buffer();
     let stats =
@@ -1163,7 +1171,18 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
     // Pad this, since something (LLVM, presumably) is cutting off the
     // remaining % 4 bytes.
     buf_w.write(&[0u8, 0u8, 0u8, 0u8]);
-    flate::deflate_buf(io::mem_buffer_buf(buf))
+
+    // FIXME #3396: weird bug here, for reasons unclear this emits random
+    // looking bytes (mostly 0x1) if we use the version byte-array constant
+    // above; so we use a string constant inline instead.
+    //
+    // Should be:
+    //
+    //   vec::from_slice(metadata_encoding_version) +
+
+    (do str::as_bytes(~"rust\x00\x00\x00\x01") |bytes| {
+        vec::slice(bytes, 0, 8)
+    }) + flate::deflate_buf(io::mem_buffer_buf(buf))
 }
 
 // Get the encoded string for a type
diff --git a/src/rustc/metadata/loader.rs b/src/rustc/metadata/loader.rs
index c6f53377f1f..2c16e6a4206 100644
--- a/src/rustc/metadata/loader.rs
+++ b/src/rustc/metadata/loader.rs
@@ -185,11 +185,30 @@ fn get_metadata_section(os: os,
         if name == meta_section_name(os) {
             let cbuf = llvm::LLVMGetSectionContents(si.llsi);
             let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
+            let mut found = None;
             unsafe {
                 let cvbuf: *u8 = unsafe::reinterpret_cast(&cbuf);
-                let v = vec::unsafe::from_buf(cvbuf, csz);
-                let inflated = flate::inflate_buf(v);
-                return Some(@inflated);
+                let vlen = vec::len(encoder::metadata_encoding_version);
+                debug!("checking %u bytes of metadata-version stamp",
+                       vlen);
+                let minsz = uint::min(vlen, csz);
+                let mut version_ok = false;
+                do vec::unsafe::form_slice(cvbuf, minsz) |buf0| {
+                    version_ok = (buf0 ==
+                                  encoder::metadata_encoding_version);
+                }
+                if !version_ok { return None; }
+
+                let cvbuf1 = ptr::offset(cvbuf, vlen);
+                debug!("inflating %u bytes of compressed metadata",
+                       csz - vlen);
+                do vec::unsafe::form_slice(cvbuf1, csz-vlen) |buf| {
+                    let inflated = flate::inflate_buf(buf);
+                    found = move Some(@(move inflated));
+                }
+                if found != None {
+                    return found;
+                }
             }
         }
         llvm::LLVMMoveToNextSection(si.llsi);
diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs
index 71e1ba8ac16..6edccf0edec 100644
--- a/src/rustc/middle/trans/common.rs
+++ b/src/rustc/middle/trans/common.rs
@@ -970,13 +970,19 @@ fn C_array(ty: TypeRef, elts: ~[ValueRef]) -> ValueRef unsafe {
 }
 
 fn C_bytes(bytes: ~[u8]) -> ValueRef unsafe {
+    return llvm::LLVMConstString(
+        unsafe::reinterpret_cast(&vec::unsafe::to_ptr(bytes)),
+        bytes.len() as c_uint, True);
+}
+
+fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef unsafe {
     return llvm::LLVMConstString(
         unsafe::reinterpret_cast(&vec::unsafe::to_ptr(bytes)),
         bytes.len() as c_uint, False);
 }
 
 fn C_shape(ccx: @crate_ctxt, bytes: ~[u8]) -> ValueRef {
-    let llshape = C_bytes(bytes);
+    let llshape = C_bytes_plus_null(bytes);
     let llglobal = str::as_c_str(fmt!("shape%u", ccx.names(~"shape")), |buf| {
         llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
     });
diff --git a/src/test/compile-fail/bad-module.rs b/src/test/compile-fail/bad-module.rs
index 79f12293616..8a49ac79b8b 100644
--- a/src/test/compile-fail/bad-module.rs
+++ b/src/test/compile-fail/bad-module.rs
@@ -1,3 +1,3 @@
-// error-pattern: unresolved import
+// error-pattern: unresolved name
 
 fn main() { let foo = thing::len(~[]); }