Skip to content

Fix concurrent map access in azurekeyvault and httpjson providers - #1250

Merged
yxxhero merged 1 commit into
helmfile:mainfrom
pathob:fix/provider-cache-races
Jul 23, 2026
Merged

Fix concurrent map access in azurekeyvault and httpjson providers#1250
yxxhero merged 1 commit into
helmfile:mainfrom
pathob:fix/provider-cache-races

Conversation

@pathob

@pathob pathob commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Both providers lazily populate an internal cache map (Key Vault clients, fetched JSON documents) without synchronization. When helmfile runs with concurrency > 1, parallel goroutines resolving refs crash the process with 'fatal error: concurrent map writes'. Guard each cache with a mutex that only covers map access. Credential setup and document fetching run outside the lock, so different vaults and URLs can initialize in parallel. Cache stores double-check for entries created concurrently and keep the first one as canonical. Also add regression tests that fail on the unfixed code when run with the Go race detector.


Disclaimer: This change was implemented using Claude Fable 5 based on the stack trace that I provided from one of our CI runs where we extensively use the azurekeyvault provider. This issue has been there "forever", but we lived with it by disabling concurrency in Helmfile and accepting the much longer deployment times. The recent developments in AI motivated me to finally find and fix this issue now. I also asked it to find similar issues and it came up with this fix for the httpjson provider as well.

@pathob
pathob force-pushed the fix/provider-cache-races branch 2 times, most recently from 54cbdb4 to 69f62e1 Compare July 22, 2026 19:09
@yxxhero
yxxhero requested a review from Copilot July 23, 2026 13:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses data races in provider-level caches that previously caused fatal error: concurrent map writes when refs were resolved concurrently (e.g., Helmfile concurrency > 1). It adds synchronization around lazily populated cache maps in the azurekeyvault and httpjson providers and introduces regression tests aimed at catching the issue under the race detector.

Changes:

  • Add mutex protection for the httpjson provider’s lazy JSON document cache.
  • Add mutex protection for the azurekeyvault provider’s lazy Key Vault client cache.
  • Add concurrency-focused regression tests for both providers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pkg/providers/httpjson/httpjson.go Adds a mutex and refactors JSON doc caching to avoid concurrent map writes.
pkg/providers/httpjson/httpjson_test.go Adds a concurrent GetString regression test for the httpjson cache.
pkg/providers/azurekeyvault/azurekeyvault.go Adds a mutex and refactors client caching to avoid concurrent map writes.
pkg/providers/azurekeyvault/azurekeyvault_test.go Adds a concurrent client-creation regression test for the azurekeyvault cache.

Comment thread pkg/providers/httpjson/httpjson.go Outdated
Comment thread pkg/providers/azurekeyvault/azurekeyvault.go
@pathob
pathob force-pushed the fix/provider-cache-races branch from 69f62e1 to 9de1ed7 Compare July 23, 2026 14:25
@pathob
pathob requested a review from Copilot July 23, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread pkg/providers/azurekeyvault/azurekeyvault_test.go Outdated
Both providers lazily populate an internal cache map (Key Vault clients,
fetched JSON documents) without synchronization. When helmfile runs with
concurrency > 1, parallel goroutines resolving refs crash the process
with 'fatal error: concurrent map writes'. Guard each cache with a mutex
that only covers map access. Credential setup and document fetching run
outside the lock, so different vaults and URLs can initialize in
parallel. Cache stores double-check for entries created concurrently and
keep the first one as canonical. Also add regression tests that fail on
the unfixed code when run with the Go race detector.

Signed-off-by: Patrick Hobusch <patrick@hobusch.net>
@pathob
pathob force-pushed the fix/provider-cache-races branch from 9de1ed7 to 0c184f9 Compare July 23, 2026 14:32
@pathob
pathob requested a review from Copilot July 23, 2026 14:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@yxxhero
yxxhero merged commit d0ceae7 into helmfile:main Jul 23, 2026
5 checks passed
@pathob
pathob deleted the fix/provider-cache-races branch July 24, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants