Skip to content

Azurite returns duplicate odata.etag in table rows for table cloned with Azure Storage Explorer #1536

Closed

Description

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

table

Which version of the Azurite was used?

3.17.1

Where do you get Azurite? (npm, DockerHub, NuGet, Visual Studio Code Extension)

npm via Rider Azure plugin

What's the Node.js version?

12.18.3

What problem was encountered?

Duplicate property odata.etag found in serialized json response after querying on RowKey. This leads to a System.Private.CoreLib: Exception while executing function: (...). System.Private.CoreLib: An item with the same key has already been added. Key: odata.etag. in Azure.Data.Tables v12.5.0.

Partial stack trace:

Function '... (Activity)' failed with an error. Reason: System.ArgumentException: An item with the same key has already been added. Key: odata.etag
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at Azure.Data.Tables.Models.TableEntityQueryResponse.DeserializeTableEntityQueryResponse(JsonElement element)
   at Azure.Data.Tables.TableRestClient.QueryEntitiesAsync(String table, Nullable`1 timeout, String nextPartitionKey, String nextRowKey, QueryOptions queryOptions, CancellationToken cancellationToken)
   at Azure.Data.Tables.TableClient.<>c__DisplayClass49_0`1.<<QueryAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Azure.Core.PageableHelpers.FuncAsyncPageable`1.AsPages(String continuationToken, Nullable`1 pageSizeHint)+MoveNext()
   at Azure.Core.PageableHelpers.FuncAsyncPageable`1.AsPages(String continuationToken, Nullable`1 pageSizeHint)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at Azure.AsyncPageable`1.GetAsyncEnumerator(CancellationToken cancellationToken)+MoveNext()
   at Azure.AsyncPageable`1.GetAsyncEnumerator(CancellationToken cancellationToken)+MoveNext()
   at Azure.AsyncPageable`1.GetAsyncEnumerator(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()

Steps to reproduce the issue?

  1. Start Azurite
  2. Clone a table with Microsoft Azure Storage Explorer v1.23.1
  3. Query the cloned table in code (C#) using Azure.Data.Tables v12.5.0

Extract from Azurite debug log, trimmed:

2022-06-10T06:36:18.665Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: TableStorageContextMiddleware: RequestMethod=GET RequestURL=http://127.0.0.1/devstoreaccount1/Office365UserDetails()?$format=application%2Fjson%3Bodata%3Dminimalmetadata&$filter=%28%28PartitionKey%20eq%20%27acme%27%29%20and%20%28RowKey%20ge%20%272022-02-13%27%29%29%20and%20%28RowKey%20lt%20%272022-02-14%27%29 RequestHeaders:{"host":"127.0.0.1:10002","x-ms-version":"2019-02-02","dataserviceversion":"3.0","accept":"application/json; odata=minimalmetadata","x-ms-client-request-id":"4a9abf9d-2b33-4929-a11b-545089905dfb","x-ms-return-client-request-id":"true","user-agent":"azsdk-net-Data.Tables/12.5.0 (.NET 6.0.4; Microsoft Windows 10.0.19044)","x-ms-date":"Fri, 10 Jun 2022 06:36:18 GMT","authorization":"SharedKeyLite devstoreaccount1:cwl6q0C7cMOwgwWJoYRcdtf3q88w3xILIOD48rtGNhI="} ClientIP=127.0.0.1 Protocol=http HTTPVersion=1.1
2022-06-10T06:36:18.665Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 debug: tableStorageContextMiddleware: Dispatch pattern string: /Office365UserDetails()
2022-06-10T06:36:18.665Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: tableStorageContextMiddleware: Account=devstoreaccount1 tableName=Office365UserDetails
2022-06-10T06:36:18.665Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 verbose: DispatchMiddleware: Dispatching request...
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: DispatchMiddleware: Operation=Table_QueryEntities
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 verbose: AuthenticationMiddlewareFactory:createAuthenticationMiddleware() Validating authentications.
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: TableSharedKeyLiteAuthenticator:validate() Start validation against account shared key authentication.
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: TableSharedKeyLiteAuthenticator:validate() [STRING TO SIGN]:"Fri, 10 Jun 2022 06:36:18 GMT\n/devstoreaccount1/devstoreaccount1/Office365UserDetails()"
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: TableSharedKeyLiteAuthenticator:validate() Calculated authentication header based on key1: SharedKeyLite devstoreaccount1:cwl6q0C7cMOwgwWJoYRcdtf3q88w3xILIOD48rtGNhI=
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: TableSharedKeyLiteAuthenticator:validate() Signature 1 matched.
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 verbose: DeserializerMiddleware: Start deserializing...
2022-06-10T06:36:18.666Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: HandlerMiddleware: DeserializedParameters={"options":{"queryOptions":{"format":"application/json;odata=minimalmetadata","filter":"((PartitionKey eq 'acme') and (RowKey ge '2022-02-13')) and (RowKey lt '2022-02-14')"},"requestId":"4a9abf9d-2b33-4929-a11b-545089905dfb","dataServiceVersion":"3.0"},"version":"2019-02-02"}
2022-06-10T06:36:18.684Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 debug: TableHandler:queryEntities() Raw response string is "{\"odata.metadata\":\"http://127.0.0.1:10002/devstoreaccount1/$metadata#Tables/@Element\",\"value\":[{\"odata.etag\":\"W/\\\"datetime'2022-06-10T06%3A21%3A42.279353Z'\\\"\",\"PartitionKey\":\"acme\",\"RowKey\":\"2022-02-13:user@acme.com\",\"odata.etag\":\"W/\\\"datetime'2022-06-09T10%3A28%3A59.435654Z'\\\"\",\"ReportDate\":\"2022-02-13\",\"CustomerId\":\"acme\",\"ReportRefreshDate\":\"2022-02-13\",\"UserPrincipalName\":\"user@acme.com\"}]}"
2022-06-10T06:36:18.684Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 verbose: SerializerMiddleware: Start serializing...
2022-06-10T06:36:18.684Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: Serializer: Start returning stream body.
2022-06-10T06:36:18.687Z 7653d0fa-125c-49f1-ace1-4d0d93cac7e4 info: EndMiddleware: End response. TotalTimeInMS=22 StatusCode=200 StatusMessage=OK Headers={"server":"Azurite-Table/3.17.1","content-type":"application/json;odata=minimalmetadata","x-ms-client-request-id":"4a9abf9d-2b33-4929-a11b-545089905dfb","x-ms-request-id":"7653d0fa-125c-49f1-ace1-4d0d93cac7e4","x-ms-version":"2021-06-08","date":"Fri, 10 Jun 2022 06:36:18 GMT"}

The relevant details are in the raw response string, formatted. Property odata.etag found twice:

[
  {
    "odata.etag": "W/\"datetime'2022-06-10T06%3A21%3A42.279353Z'\"",
    "PartitionKey": "acme",
    "RowKey": "2022-02-13:user@acme.com",
    "odata.etag": "W/\"datetime'2022-06-09T10%3A28%3A59.435654Z'\"",
    "ReportDate": "2022-02-13",
    "CustomerId": "acme",
    "ReportRefreshDate": "2022-02-13",
    "UserPrincipalName": "user@acme.com"
  }
]

Have you found a mitigation/solution?

No

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

table-storageRelating to Azurite table storage implementation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions