Describe the bug
When trying to aquire a lease on a blob I get the an exception.
Expected behavior
I should be able to acquire a lease on this blob.
Actual behavior (include Exception or Stack Trace)
The value for one of the HTTP headers is not in the correct format.
RequestId:<guid>
Time:2020-09-30T10:28:47.8781946Z
Status: 400 (The value for one of the HTTP headers is not in the correct format.)
ErrorCode: InvalidHeaderValue
Headers:
Server: Windows-Azure-Blob/1.0,Microsoft-HTTPAPI/2.0
x-ms-request-id: <guid>
x-ms-client-request-id: <guid>
x-ms-version: 2019-12-12
x-ms-error-code: InvalidHeaderValue
Date: Wed, 30 Sep 2020 10:28:47 GMT
Content-Length: 328
Content-Type: application/xml
To Reproduce
```c#
BlockBlobClient blockBlobClient = new BlockBlobClient(
"connectionstring",
"containername",
"blob");
BlobLeaseClient blc = blockBlobClient.GetBlobLeaseClient();
//exception here
BlobLease bl = await blc.AcquireAsync(new TimeSpan(0, 0, 10));
```
Environment:
I did actually get something working https://stackoverflow.com/a/64136116/542251
But the above looks to me like it should work. So why doesn't it?
I'd suggest at the very least that the error message is confusing/vague.
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage.
Thank you for your feedback. Tagging and routing to the team best able to assist.
Hi,
"A non-infinite lease can be between 15 and 60 seconds". https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob (see x-ms-lease-duration)
That's why the stackoverflow link you used worked cause it was 30 seconds while the snippet you provided was 10 seconds. So the error code you got back from the service "InvalidHeaderValue" is correct.
Please re-open if you have further questions.
So why does the AcquireAsync allow me to specify a value < 15 seconds?! I still think this is a bug. I'd say:
1) the AcquireAsync should parse these inputs
2) when an invalid time is specified an error message along the lines of "x is an invalid time period" should be returned, not the very cryptic "The value for one of the HTTP headers is not in the correct format.". I mean why is this even talking about headers. I'm not using the REST api directly. I'm using a wrapper class.
Yes @seanmcc-msft please could you re-open this ticket
Sorry could you explain why this is a bug. The SDK uses the storage service REST API. The storage service REST API only allows "A non-infinite lease can be between 15 and 60 seconds" please reference this link I posted before (https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob).

There's nothing the SDK can do about the service standard of what is allowed for a non-infinite lease value. The SDK follows the requirements of the REST API.
The error message you are getting back is directly from the service. The SDK cannot alter the error message returned by the service. Altering the error message returned by the service could lead to mishandling of errors, and misinform users when they receive back a different error. What if a different request header had an Invalid Value, then we would return the wrong error.
It's talking about headers because we specify Lease Duration in the request headers to the service (x-ms-lease-duration) (Reference document https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob#request-headers)
Hi @amanarneja . Like I said the issue here, I'd suggest, is one of clarity. Why can I specify a value of <15 seconds if this will never succeed?
You seem to be suggesting that this library is just forwarding on HTTP requests. In which case why use it at all? I could just use a HTTP client. Surely the whole point of a library is to flatten out some of this business logic?
How would anyone know this without trawling though the documentation. Someone once told me
If your answer to a problem is "we'll put that in the documentation" then you've gone wrong and should rethink
Also, like I've already stated. The error message is cryptic to the point if uselessness.
I'm a bit confused as to your issue with adding a more user friendly error message here? why not just return
A non-infinite lease can be between 15 and 60 second
in an exception? Then it's all clear to everyone. Much better than:
The value for one of the HTTP headers is not in the correct format.
@tg-msft, @kasobol-msft, could you jump in here?
The response has a payload that contain information about which header is invalid. We should either expose it or add client side validation.
@tg-msft could you jump in with why we allow users to specify values that are not valid to the service. I believe there's a SDK guideline (something like that) with allowing the service to handle error messages.
With creating more user friendly error messages, we actually have an issue already open for that. See https://github.com/Azure/azure-sdk-for-net/issues/14469
Client-side validation can result in really painful forward compatibility problems.
To better illustrate, let's pretend we added client-side validation for an operation like Set Blob Tags. There's a maximum of 10 tags so why not enforce that before we send an expensive request across the network? It seems safe.
It's harder to imagine something like this happening with blob leases, but I could see someone getting the current lease duration via GetProperties and calling LeaseClient.Break with it (i.e., I'll let you finish one lease, but not renew it).
If we can't make the error messages better with #14469, then the most we should do is post facto client-side validation where we catch the error, determine it's because the lease was out of range, and then wrap it in an exception that's more helpful to customers.
@tg-msft
The Exchange API handles this scenario nicely with paging. The response object contains a .HasMore property, which can be evaluated by client-side code.
The response has a payload that contain information about which header is invalid. We should either expose it or add client side validation.
This seems like a perfectly valid approach.
This issue was resolves with https://github.com/Azure/azure-sdk-for-net/pull/15986
Most helpful comment
Client-side validation can result in really painful forward compatibility problems.
To better illustrate, let's pretend we added client-side validation for an operation like Set Blob Tags. There's a maximum of 10 tags so why not enforce that before we send an expensive request across the network? It seems safe.
It's harder to imagine something like this happening with blob leases, but I could see someone getting the current lease duration via
GetPropertiesand callingLeaseClient.Breakwith it (i.e., I'll let you finish one lease, but not renew it).If we can't make the error messages better with #14469, then the most we should do is post facto client-side validation where we catch the error, determine it's because the lease was out of range, and then wrap it in an exception that's more helpful to customers.