diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py
index 85209dc522..11b42179ed 100644
--- a/swift/proxy/controllers/obj.py
+++ b/swift/proxy/controllers/obj.py
@@ -650,9 +650,12 @@ class BaseObjectController(Controller):
         pile = GreenPile(len(nodes))
 
         for nheaders in outgoing_headers:
-            # RFC2616:8.2.3 disallows 100-continue without a body
-            if (req.content_length > 0) or req.is_chunked:
-                nheaders['Expect'] = '100-continue'
+            # RFC2616:8.2.3 disallows 100-continue without a body,
+            # so switch to chunked request
+            if nheaders.get('Content-Length') == '0':
+                nheaders['Transfer-Encoding'] = 'chunked'
+                del nheaders['Content-Length']
+            nheaders['Expect'] = '100-continue'
             pile.spawn(self._connect_put_node, node_iter, partition,
                        req, nheaders, self.app.logger.thread_locals)
 
@@ -894,12 +897,13 @@ class ReplicatedObjectController(BaseObjectController):
                 logger=self.app.logger,
                 need_multiphase=False)
         else:
+            te = ',' + headers.get('Transfer-Encoding', '')
             putter = Putter.connect(
                 node, part, req.swift_entity_path, headers,
                 conn_timeout=self.app.conn_timeout,
                 node_timeout=self.app.node_timeout,
                 logger=self.app.logger,
-                chunked=req.is_chunked)
+                chunked=te.endswith(',chunked'))
         return putter
 
     def _transfer_data(self, req, data_source, putters, nodes):
diff --git a/test/probe/test_object_conditional_requests.py b/test/probe/test_object_conditional_requests.py
new file mode 100644
index 0000000000..29021ba681
--- /dev/null
+++ b/test/probe/test_object_conditional_requests.py
@@ -0,0 +1,79 @@
+# Copyright (c) 2017 OpenStack Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import uuid
+
+from swift.common.manager import Manager
+from swiftclient import client
+
+from test.probe.brain import BrainSplitter
+from test.probe.common import ReplProbeTest
+
+
+def chunker(body):
+    '''Helper to ensure swiftclient sends a chunked request.'''
+    yield body
+
+
+class TestPutIfNoneMatchRepl(ReplProbeTest):
+    def setUp(self):
+        super(TestPutIfNoneMatchRepl, self).setUp()
+        self.container_name = 'container-%s' % uuid.uuid4()
+        self.object_name = 'object-%s' % uuid.uuid4()
+        self.brain = BrainSplitter(self.url, self.token, self.container_name,
+                                   self.object_name, 'object',
+                                   policy=self.policy)
+
+    def _do_test(self, overwrite_contents):
+        self.brain.put_container()
+        self.brain.stop_primary_half()
+        # put object to only 1 of 3 primaries
+        self.brain.put_object(contents='VERIFY')
+        self.brain.start_primary_half()
+
+        # Restart services and attempt to overwrite
+        with self.assertRaises(client.ClientException) as exc_mgr:
+            self.brain.put_object(headers={'If-None-Match': '*'},
+                                  contents=overwrite_contents)
+        self.assertEqual(exc_mgr.exception.http_status, 412)
+
+        # make sure we're GETting from the servers that missed the original PUT
+        self.brain.stop_handoff_half()
+
+        # verify the PUT did not complete
+        with self.assertRaises(client.ClientException) as exc_mgr:
+            client.get_object(
+                self.url, self.token, self.container_name, self.object_name)
+        self.assertEqual(exc_mgr.exception.http_status, 404)
+
+        # for completeness, run replicators...
+        Manager(['object-replicator']).once()
+
+        # ...and verify the object was not overwritten
+        _headers, body = client.get_object(
+            self.url, self.token, self.container_name, self.object_name)
+        self.assertEqual(body, 'VERIFY')
+
+    def test_content_length_nonzero(self):
+        self._do_test('OVERWRITE')
+
+    def test_content_length_zero(self):
+        self._do_test('')
+
+    def test_chunked(self):
+        self._do_test(chunker('OVERWRITE'))
+
+    def test_chunked_empty(self):
+        self._do_test(chunker(''))
diff --git a/test/unit/proxy/controllers/test_obj.py b/test/unit/proxy/controllers/test_obj.py
index 0efca8f488..77e931670a 100644
--- a/test/unit/proxy/controllers/test_obj.py
+++ b/test/unit/proxy/controllers/test_obj.py
@@ -1083,13 +1083,13 @@ class TestReplicatedObjController(BaseObjectControllerMixin,
         for connection_id, info in put_requests.items():
             body = ''.join(info['chunks'])
             headers = info['headers']
-            if chunked:
+            if chunked or not test_body:
                 body = unchunk_body(body)
                 self.assertEqual('100-continue', headers['Expect'])
                 self.assertEqual('chunked', headers['Transfer-Encoding'])
             else:
                 self.assertNotIn('Transfer-Encoding', headers)
-            if body:
+            if body or not test_body:
                 self.assertEqual('100-continue', headers['Expect'])
             else:
                 self.assertNotIn('Expect', headers)
diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py
index 546d13634f..f53f87c858 100644
--- a/test/unit/proxy/test_server.py
+++ b/test/unit/proxy/test_server.py
@@ -2584,9 +2584,12 @@ class TestReplicatedObjectController(
         def test_connect(ipaddr, port, device, partition, method, path,
                          headers=None, query_string=None):
             if path == '/a/c/o.jpg':
-                if 'expect' in headers or 'Expect' in headers:
-                    test_errors.append('Expect was in headers for object '
-                                       'server!')
+                if headers.get('Transfer-Encoding') != 'chunked':
+                    test_errors.append('"Transfer-Encoding: chunked" should '
+                                       'be in headers for object server!')
+                if 'Expect' not in headers:
+                    test_errors.append('Expect should be in headers for '
+                                       'object server!')
 
         with save_globals():
             controller = ReplicatedObjectController(