A two-day debug of persistent 401s on azurerm_storage_table_entity in Topaz uncovered four layered bugs: URL encoding, missing MERGE verb, upsert semantics, and a disposed stream.
Key Takeaways
Root cause: ASP.NET Core silently decodes HttpRequest.Path; signing must use IHttpRequestFeature.RawTarget to match the wire-format percent-encoded URL Terraform sends.
InsertOrMergeTableEntityEndpoint only declared POST; go-azure-sdk sends MERGE, causing a routing 404 after auth was fixed.
Azure Table Storage Insert-or-Merge semantics require an upsert path; the existing UpdateEntity threw EntityNotFoundException on missing entities instead of creating them.
StreamReader disposed the body stream before the upsert fallback could read it; fix was buffering into MemoryStream with leaveOpen: true before entering UpdateEntity.
Each bug was invisible until the previous one was resolved – the fix sequence was necessarily serial, not parallelizable.