Azure / azure-storage-java

Microsoft Azure Storage Library for Java
https://docs.microsoft.com/en-us/java/api/overview/azure/storage
MIT License
189 stars 163 forks source link

The metadata specified is invalid. It has characters that are not permitted. #524

Closed helderribeirosousa closed 4 years ago

helderribeirosousa commented 4 years ago

Which service(blob, file, queue, table) does this issue concern?

Blob Storage

Which version of the SDK was used?

8.6.0

What problem was encountered?

Whenever I upload a blob after setting the metadata I get the following error:

com.microsoft.azure.storage.StorageException: The metadata specified is invalid. It has characters that are not permitted. Stack trace: at com.microsoft.azure.storage.StorageException.translateException(StorageException.java:87) ~[azure-storage-8.6.0.jar:na] at com.microsoft.azure.storage.core.StorageRequest.materializeException(StorageRequest.java:305) ~[azure-storage-8.6.0.jar:na] at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:196) ~[azure-storage-8.6.0.jar:na] at com.microsoft.azure.storage.blob.CloudBlockBlob.uploadFullBlob(CloudBlockBlob.java:1035) ~[azure-storage-8.6.0.jar:na] at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:864) ~[azure-storage-8.6.0.jar:na] at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:743) ~[azure-storage-8.6.0.jar:na] at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:712) ~[azure-storage-8.6.0.jar:na]

Have you found a mitigation/solution?

I've encoded both the metadata keys and values to base64 and hexadecimal but I still get this error.

Any ideas? Thank you!

P.S.: I think your implementation method interfaces should expect the metadata type to be Map<String,String> which is the high-level definition of HashMap<String,String> that you expecting in your current implementation.

rickle-msft commented 4 years ago

@helderribeirosousa Thank you for posting this! If it's not sensitive, can you please share the values you're trying to set as metadata?

P.S. You're probably right :). That decision was made long before my time here, and I'm not sure why they would have required a specific implementation for metadata

rickle-msft commented 4 years ago

Also, if you take a look at the REST docs under the x-ms-meta request header, you'll see that the keys have to be a valid C# identifier. Perhaps that is whey base64 was not working as '+' and '=' are not valid for c# identifiers. I'm not sure why hex would fail in that case.

helderribeirosousa commented 4 years ago

Hey @rickle-msft, thank you for replying such short notice.

It is failing with hex. The values I'm trying are:

(KEY -> VALUE) 636f6e74656e742d6c656e677468 -> 3130353135 66696c656e616d65 -> 313538323832383636382e706466 636f6e74656e742d74797065 -> 6170706c69636174696f6e2f706466 63726561746564 -> 31353832383238363638

rickle-msft commented 4 years ago

@helderribeirosousa I see. I think those values are failing because a C# identifier can't start with a number. I saw the failure when uploading these, and got it to succeed by prepending the letter 'a' to the front, which seems to support my theory.

Basically, your metadata key needs to be something that you could use as a variable name in a (C#) program if that helps you pick valid metadata keys.

helderribeirosousa commented 4 years ago

@rickle-msft I've added the underscore prefix to all keys and it's working fine now.

In my honest opinion, and for what it is worth, the developer should be able to name the keys and assign whatever values he/she pleases.

Thank you for solving this issue @rickle-msft!

rickle-msft commented 4 years ago

Glad you were able to find a workable solution. I think your preference for arbitrary key values is reasonable. Unfortunately, this is a limitation dictated by the service.

Please let us know if we can continue to support you in any way.