title: Unable to set object metadata in AWS S3 using HTTP headers
body: <p>My goal is to upload a binary file to an S3 bucket, and to tag it with two pieces of metadata. I'm not developing on any of the platforms supported by the AWS SDK, so I'm (essentially) constructing my own HTTP requests.  The files are making it into S3, but despite following the instructions, the metadata isn't appearing (neither in S3's web-based GUI, nor when I make HEAD requests), and I'm trying to understand what I'm missing.</p>
  
  <p>The <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#object-metadata" rel="nofollow">documentation</a> says (emphasis mine):</p>
  
  <blockquote>
    <p>When uploading an object, you can also assign metadata to the object. You provide this optional information as a name-value pair when you send a PUT or POST request to create the object. When uploading objects using the REST API the optional <strong>user-defined metadata names must begin with "x-amz-meta-" to distinguish them from other HTTP headers</strong>.</p>
  </blockquote>
  
  <p>By pointing my app at a local test HTTP server that simply logs the entirety of all requests, I've confirmed that I'm sending the header the doc suggests:</p>
  
  <pre><code>POST / HTTP/1.1
  host: 192.168.1.8:8082
  user-agent: test
  accept-language: en-us
  accept-encoding: gzip, deflate
  accept: */*
  content-type: multipart/form-data; boundary=----fixed.boundary.value
  connection: keep-alive
  content-length: 852705
  x-amz-meta-testheader: value-ONE
  
  
  ------fixed.boundary.value
  Content-Disposition: form-data; name="metadata"
  
  {"testheader":"value-TWO"}
  ------fixed.boundary.value
  Content-Disposition: form-data; name="testheader"
  
  value-THREE
  ------fixed.boundary.value
  Content-Disposition: form-data; name="upload"
  
  {"testheader":"value-FOUR"}
  ------fixed.boundary.value
  Content-Disposition: form-data; name="key"
  
  binaryfilename.ext
  ------fixed.boundary.value
  Content-Disposition: form-data; name="acl"
  
  public-read
  ------fixed.boundary.value
  Content-Disposition: form-data; name="file"; filename="binaryfilename.ext"
  Content-Type: application/octet-stream
  Content-Length: 851750
  
  &lt;inlined binary content&gt;
  ------fixed.boundary.value--
  </code></pre>
  
  <p>This request includes several variations on the desired metadata. I'm using a third-party library to handle the file upload, and it generates the entire request. Its API is poorly-documented, so when S3 wasn't reacting the way I hoped, I threw in a few variations on where to insert the metadata, plus some other things I've seen on the web, in the hopes that something would stick. So far nothing has. None of the official documentation addresses the <code>multipart/form-data</code> scenario explicitly at the HTTP level, so I've had to apply the shotgun approach and guess where in the body S3 might look for metadata.</p>
  
  <p>It's my understanding from the documentation that the <code>x-amz-meta-*</code> headers should be sufficient to tag the uploaded file. So, why isn't it working? Does the automatic metadata functionality depend on bucket configuration? Is this a paid feature? Does this only work for data (or "objects") that are transported as text? Are there other ways to debug this?</p>
  
  <p>Any help is appreciated. I need to understand this at the HTTP layer, so let's stick to that.</p>