Use conditional requests

Important

This feature is in Beta. To use it, a workspace admin must turn on Files API V3 with Large File Upload Support from the Previews page. See Manage Azure Databricks previews.

Conditional requests let you make an operation depend on the current state of the target file, so the request only takes effect if the file is in the state you expect. This lets you avoid wasted transfers, prevent lost updates from concurrent writers, and create or delete files safely.

Files API 3.0 supports the four standard HTTP conditional headers from RFC 9110.

Header Compares against Honored on
If-Match The file's ETag Reads, writes, and deletes
If-None-Match The file's ETag Reads and writes
If-Modified-Since The file's Last-Modified time Reads only
If-Unmodified-Since The file's Last-Modified time Reads only

If-Modified-Since and If-Unmodified-Since apply only to read operations (GET and HEAD). They are not supported on upload or delete.

When the condition is not met, the server does not perform the operation and returns one of the following statuses:

  • 304 Not Modified, when a GET or HEAD request with If-None-Match or If-Modified-Since fails. It confirms that your cached copy is still valid, so there is no need to send the file again.
  • 412 Precondition Failed, when any other condition fails. The read, upload, or delete is not performed.

Validators: ETag and Last-Modified

A conditional request compares a validator you supply against the file's current validator. The Files API returns both validators as response headers, so you can capture them and use them in a later request:

  • ETag: an opaque identifier for the file's current content. Store the exact value the server returned, including its surrounding quotes, and send it back unchanged. Do not parse or construct it.
  • Last-Modified: the file's last modification time, as an HTTP-date.

Both validators are returned on GET and HEAD responses. ETag is also returned on PUT and the multipart complete-upload response.

Last-Modified has a precision of one second. If-Modified-Since and If-Unmodified-Since can't detect several changes made within the same second, so don't rely on them for precise concurrency control. Use ETag with If-Match or If-None-Match instead.

Conditional reads

On GET and HEAD, all four conditional headers are honored. The most common use is cache revalidation: you have a previously downloaded copy and want the server to send the bytes again only if they have changed.

Send If-None-Match with the ETag of your cached copy, or If-Modified-Since with the time you last fetched it. If the file is unchanged, the server returns 304 Not Modified with no body and you keep using your cached copy. If it has changed, the server returns 200 OK with the new content.

To revalidate a cached file, send its ETag and download the body only if the file changed:

GET /api/3.0/fs/files/Volumes/main/default/reports/report.csv
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

The other two read headers assert the opposite condition. If-Match returns the file only if its ETag still matches, and otherwise returns 412. If-Unmodified-Since returns it only if the file has not changed since the given time, and otherwise returns 412.

You can send at most two conditional headers on a read. Requests with more are not supported. When you send two, their precedence follows RFC 9110.

Conditional writes

On PUT, you can use If-None-Match and If-Match to guard an upload against the current state of the file:

  • If-None-Match: * saves the file only if it does not already exist. This guarantees that the upload won't accidentally overwrite another upload and lose its data, which is a variation of the lost update problem. If a file already exists at the path, the request returns 412 Precondition Failed.
  • If-Match: <etag> prevents the lost update problem. It checks that the upload will not override another change made since you fetched the file. The upload succeeds only if the file's current ETag matches the one you supply. Otherwise, the request returns 412 Precondition Failed. If no file exists at the path, the request returns 404.

To create a file only if it does not already exist, send If-None-Match: *:

PUT /api/3.0/fs/files/Volumes/main/default/reports/report.csv
If-None-Match: *
Content-Type: application/octet-stream
<binary data>

200 OK

To overwrite a file only if it is still the version you last fetched, send its ETag with If-Match:

PUT /api/3.0/fs/files/Volumes/main/default/reports/report.csv
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Content-Type: application/octet-stream
<binary data>

200 OK

The following forms are not supported on PUT: a list of ETags, If-Match: *, If-None-Match with a specific ETag, If-Modified-Since, and If-Unmodified-Since.

For a multipart upload, send the conditional header on the initiate-upload call. The Files API stores it and evaluates it when the upload completes, so the condition applies to the final assembled file. You can use the same two headers as on PUT: If-None-Match: * and If-Match: <etag>. Conditional headers on the complete-upload or abort-upload call itself are not supported.

Conditional deletes

DELETE is idempotent. Deleting a file that does not exist still returns 204 No Content. This makes cleanup simple, but a plain DELETE can't tell you whether you removed the version you intended. To make a delete conditional, send If-Match:

  • If-Match: <etag> deletes the file only if its current ETag matches the one you supply. If another user modified the file after you fetched it, the request returns 412 Precondition Failed instead of removing their change. If the file no longer exists, the request returns 404.
  • If-Match: * deletes the file only if it exists. The request returns 204 if the file existed and 404 if it did not.
DELETE /api/3.0/fs/files/Volumes/main/default/reports/report.csv
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

204 No Content

The remaining conditional headers (If-None-Match, If-Modified-Since, and If-Unmodified-Since) are not supported on DELETE.