Troubleshooting
Find the cause when a bucket cannot be deleted, the API rejects a create request, or the Azion CLI reports a success it did not produce.
This page covers what Object Storage does that you did not expect: a bucket that refuses to be deleted, a create request the API rejects, an object served with the wrong content type, a write that answers 17013, a list request that finds nothing, an object an application does not return, and the two Azion CLI commands that report an outcome they did not produce.
A bucket cannot be deleted and the API returns 17006
A DELETE on the bucket answers HTTP 400, with the title Cannot Delete Non Empty Bucket and the detail Unable to delete a non-empty bucket. Additionally, objects deleted within the last 24 hours are also taken into consideration.
Two conditions block the deletion, and the detail names both. A bucket that holds one object cannot be deleted. A bucket emptied within the last 24 hours cannot be deleted either, because Object Storage removes a deleted object permanently only after a 24-hour grace period. A bucket that never held an object deletes at once.
- Empty the bucket: list the keys with
GET /buckets/{bucket_name}/objects, then send oneDELETEper key. For the operations, refer to Buckets and objects. - Wait out the grace period: send the
DELETEagain 24 hours after the last object was removed. - Expect the same refusal from the Azion CLI: the 24-hour rule applies to
azion delete storage bucketas well.
The DELETE then answers HTTP 200 with state set to executed, and the bucket leaves GET /buckets.
A bucket name is refused and the API returns 17000 or 17001
A POST /buckets answers HTTP 400 under one of two titles, and source.pointer names /data/name.
Bucket Already Exists means the name is taken. A bucket name is unique across every Azion account, so another account can hold it, and the detail reads Bucket name '<name>' is already in use. Bucket Name Not Available means the name begins with azion, which Object Storage reserves.
17000,Bucket Already Exists: send another name. A name that carries your project or account as a prefix collides less often than a generic one.17001,Bucket Name Not Available: remove theazionprefix from the name.- Check the name against the other rules: a name is 6 to 63 characters, and it holds letters, numbers, and the hyphen. For each bound, refer to Object Storage limits.
The create request then answers HTTP 201 with state set to executed, and the response carries the bucket.
The access level is refused and the API returns 10059 or 10039
A POST /buckets answers HTTP 400 with the title Required Field under code 10059, or the title Invalid Choice under code 10039. In both cases source.pointer names workloads_access.
workloads_access is required on create, and it accepts exactly three values: read_only, read_write, and restricted. 10059 means the field is absent from the body. A body that sends edge_access produces the same error, because the API does not read edge_access and the create schema does not store an unknown field. 10039 means the value sits outside the three: a body carrying private answers "private" is not a valid choice.
- Name the field
workloads_access: the field carries that name in the API, in the Azion CLI, and in theazionlibrary.edge_accessis not part of any of them. - Replace
privatewithrestricted:restrictedis the value that keeps the Azion platform out of the bucket. - Check which level the bucket needs: for what each value permits, refer to Access levels.
The create request then answers HTTP 201, and reading the bucket back shows workloads_access with the value you sent.
An object is served with the wrong content type
A download of the object returns a Content-Type the object was not uploaded with. A file uploaded as an image is served as text/plain, or a JSON body is served as application/octet-stream.
The stored content type comes from the Content-Type header of the upload request. When the request carries no Content-Type, Object Storage detects the type from the object itself. The Storage-Content-Type header, which the API specification documents, is accepted and ignored, so a request that sets only that header stores a detected type rather than the one you named.
- Upload the object again with
Content-Type: the header sets the stored type, and aPOSTto a key that already exists replaces the object and answers201. - Drop
Storage-Content-Typefrom the request: the header changes nothing, and it hides the missingContent-Type. - Read the type back:
GET /buckets/{bucket_name}/objects/{object_key}returns the object with the type it holds.
Every later request for the object then returns the type you sent. For the upload operations, refer to Buckets and objects.
A PUT to an object key returns 17013
A PUT on /buckets/{bucket_name}/objects/{object_key} answers HTTP 404, with the title Object Does Not Exist. The bucket exists and the request body is valid.
PUT maps to update_object_key, which replaces an object that is already stored. It never creates one. POST maps to create_object_key, which is the operation that creates the key, including every prefix inside it: a POST to objects/folder/sub/data.json needs no prior step.
POSTthe key first: the create answers201withstateset toexecutedanddata.object_keynaming the key.- Keep
PUTfor replacements: once the key exists,PUTanswers200or202. - Or
POSTevery time: aPOSTto a key that already exists replaces the object and answers201, so one operation covers both cases.
The object is then stored under the key, and GET /buckets/{bucket_name}/objects returns it.
A list request returns no bucket although the bucket exists
GET /buckets with name set to part of a bucket name answers 200 with count as 0 and an empty results array. The bucket filter returns nothing for any value, including an exact name.
name matches the whole bucket name exactly, although the API specification describes it as a case-insensitive partial match. The bucket filter returns no record at all. search is the parameter that matches part of a name, and workloads_access filters correctly.
- Match part of a name with
search:GET /buckets?search=my-bucketreturns every bucket whose name containsmy-bucket. - Use
nameonly with the whole name:GET /buckets?name=my-bucket-roreturns that one bucket. - Do not filter with
bucket: it returns no record, so an empty response proves nothing about the account. - Page through the list instead of filtering:
page_sizeaccepts up to 100, andpagemoves through the pages.
The response then carries the bucket in results, and count states how many buckets matched.
An object is missing from the application that serves the bucket
A list request on the bucket returns the object key, and a request to the application that serves the bucket does not return the object.
An object reaches an end user only through an application. A Connector with Connector Type set to Object Storage points at the bucket, and a Rules Engine rule sends matching requests to that connector. Two links in that chain hide an object that exists. The connector’s Prefix field narrows what it serves, so an object stored outside the prefix is unreachable through it. With no connector and no rule, no request reaches the bucket at all. The S3 endpoint does not close the gap either: it manages objects and does not deliver them to end users.
- Compare the object key with the connector’s prefix: the connector serves the objects under Prefix and nothing else.
- Confirm a rule sends the request to the connector: without the rule, the application never asks the bucket.
- Check the access level of the bucket: a
restrictedbucket cannot back an application, whileread_onlyandread_writecan. - For the whole chain, refer to Use a bucket as an application origin: it carries the connector fields and the rule.
A request that matches the rule then returns the object from the bucket.
The Azion CLI reports Bucket deletion was scheduled successfully and the bucket remains
azion delete storage bucket --name <bucket> --force prints Delete all objects from bucket, then Deleting objects..., then Bucket deletion was scheduled successfully. The bucket is still in the output of azion list storage bucket.
This is a defect in Azion CLI 4.23.0, not a rule you worked around incorrectly. --force deletes every object in the bucket and then asks the API to delete the bucket. The API refuses with 17006, because an object was removed within the last 24 hours. The command does not report that refusal, so it prints a success it did not produce. The objects are gone; the bucket is not.
- Read the bucket list before you trust the message:
azion list storage bucketstates whether the bucket survived. - Delete the bucket after the grace period: 24 hours after the last object was removed, run
azion delete storage bucket --name <bucket>without--force. - Remove objects one at a time when you want to keep the bucket:
azion delete storage object --bucket-name <bucket> --object-key <key>printsObject <key> was deleted successfully.
The delete without --force then prints Bucket <bucket> was deleted successfully, and the bucket leaves the list.
The Azion CLI reports no such file or directory for a file that exists
azion create storage object --source fails on a path you can read. From the working directory /tmp, --source /tmp/os-cli.txt answers Error: open /tmp/tmp/os-cli.txt: no such file or directory, and the file is there.
This is a defect in Azion CLI 4.23.0. The command joins the value of --source to the working directory instead of reading an absolute path as absolute, so the directory appears twice in the path it opens. The help text of the flag describes the value as an absolute path, which is the opposite of what the command accepts. azion update storage object --source behaves the same way.
- Pass a relative path: from the directory that holds the file,
--source os-cli.txtreaches it. - Run the command from the directory that holds the file: the relative path is then the file name alone.
- Upload through the API when a script needs an absolute path:
POST /buckets/{bucket_name}/objects/{object_key}takes the file as the request body.
The command then prints Object created successfully. For the storage commands and their flags, refer to Azion CLI.