{
  "slug": "conditional-write",
  "term": "Conditional write",
  "aliases": [
    "Conditional object write"
  ],
  "definition": "A conditional write changes a resource only when a server-evaluated precondition, such as a matching entity tag or the absence of a current object, holds.",
  "note": "For Amazon S3 general-purpose buckets, If-Match on PutObject or CompleteMultipartUpload compares the current destination object's ETag, while If-None-Match: * requires no current object. This is an object-level precondition, not a multi-object transaction or a test that no intervening write ever happened. Client-side checking followed by an unconditional upload does not provide the same protection. An ETag condition validates the representation under the service's ETag rules, not every metadata field or application invariant.",
  "status": "shipping",
  "advantages": [
    {
      "text": "An If-Match precondition can reject a stale replacement instead of silently overwriting a representation whose validator has changed.",
      "citationIds": [
        "c1",
        "c2"
      ]
    },
    {
      "text": "If-None-Match: * lets an S3 writer require that the destination has no current object at the write operation, without a separate check-then-create race.",
      "citationIds": [
        "c1",
        "c2"
      ]
    }
  ],
  "limitations": [
    {
      "text": "A mismatched ETag or an existing current object under If-None-Match: * causes S3 to return 412; a conflicting operation can return 409, and blindly refreshing the ETag without reconciling stale content can lose an update.",
      "citationIds": [
        "c3",
        "c6"
      ]
    },
    {
      "text": "After a 409 from CompleteMultipartUpload, S3 requires a new upload ID and re-upload of every part; retry rules therefore differ from PutObject.",
      "citationIds": [
        "c3",
        "c4"
      ]
    },
    {
      "text": "In versioned S3 buckets, If-None-Match: * permits a write when the current version is a delete marker, even if older versions remain; If-Match fails with 404 when there is no current object or the current version is a delete marker.",
      "citationIds": [
        "c2"
      ]
    },
    {
      "text": "Strong S3 read-after-write consistency does not make a separate read-modify-write sequence atomic, and S3 does not provide atomic updates across multiple keys.",
      "citationIds": [
        "c5",
        "c6"
      ]
    }
  ],
  "related": [
    "object-storage",
    "entity-tag",
    "multipart-upload",
    "compare-and-swap"
  ],
  "supersedes": [],
  "supersededBy": [],
  "firstSeen": null,
  "lastSeen": null,
  "updated": "2026-10-12",
  "citations": [
    {
      "id": "c1",
      "title": "RFC 9110: HTTP Semantics, conditional requests",
      "url": "https://www.rfc-editor.org/rfc/rfc9110.html#section-13",
      "accessed": "2026-10-12"
    },
    {
      "id": "c2",
      "title": "Amazon S3: How to prevent object overwrites with conditional writes",
      "url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html",
      "accessed": "2026-10-12"
    },
    {
      "id": "c3",
      "title": "Amazon S3 API Reference: PutObject",
      "url": "https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html",
      "accessed": "2026-10-12"
    },
    {
      "id": "c4",
      "title": "Amazon S3 API Reference: CompleteMultipartUpload",
      "url": "https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html",
      "accessed": "2026-10-12"
    },
    {
      "id": "c5",
      "title": "Amazon S3: Data consistency model",
      "url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#ConsistencyModel",
      "accessed": "2026-10-12"
    },
    {
      "id": "c6",
      "title": "Object ETags: checksums and conditional writes are different",
      "url": "https://hesela.com/analyses/object-etags-checksums-conditional-writes/",
      "accessed": "2026-10-12"
    }
  ]
}
