Skip to content

sdk/ldaputil: fix malformed error messages from errwrap placeholder - #32064

Closed
drewmullen wants to merge 1 commit into
hashicorp:mainfrom
drewmullen:fix/ldaputil-errwrap-placeholder
Closed

sdk/ldaputil: fix malformed error messages from errwrap placeholder#32064
drewmullen wants to merge 1 commit into
hashicorp:mainfrom
drewmullen:fix/ldaputil-errwrap-placeholder

Conversation

@drewmullen

Copy link
Copy Markdown
Contributor

Fixes #32063

What

Six call sites in sdk/helper/ldaputil/client.go built a format string containing the errwrap placeholder {{err}} and passed it to fmt.Errorf along with an error. fmt.Errorf does not interpret {{err}}, and the format string had no verb to consume the argument, so Go appended %!(EXTRA ...).

Let me know if you want me to adjust the test to not hardcode old behavior. it was useful for validation purposes for this PR so i left it in.

Before:

error connecting to host "ldaps://dc.example.com:636": {{err}}%!(EXTRA *ldap.Error=LDAP Result Code 200 "Network Error": dial tcp 10.0.0.1:636: i/o timeout)

After:

error connecting to host "ldaps://dc.example.com:636": LDAP Result Code 200 "Network Error": dial tcp 10.0.0.1:636: i/o timeout

Switching to %w also wraps the underlying error, so errors.Is and errors.As reach it. They could not before.

Why it went unnoticed

go vet does not flag the original form. fmt.Sprintf makes the format string non-constant, so the printf analyser skips it. Confirmed by running go vet ./helper/ldaputil/ against the unfixed code: clean.

Elsewhere in the codebase {{err}} is used correctly with errwrap.Wrapf, which does interpret it. Only these six passed it to fmt.Errorf.

Scope

All six call sites are in sdk/helper/ldaputil/client.go:

Line Message
40 error parsing url %q
107 error connecting to host %q
456 SID %#v convert failed reading Revision
460 SID %#v convert failed reading SubAuthorityCount
464 SID %#v convert failed reading IdentifierAuthority
470 SID %#v convert failed reading SubAuthority

ldaputil is used by the built-in LDAP auth method and, through vault-plugin-secrets-openldap, by the LDAP/AD secrets engines, so this affects both authentication and dynamic credential paths.

Test

Added TestSIDBytesToStringErrorFormatting, which exercises the SID conversion path (no network required) and asserts the rendered error contains neither {{err}} nor %!(EXTRA, and that errors.Is reaches the wrapped io.EOF.

Verified the test fails against the unfixed code and passes with the change:

--- FAIL: TestSIDBytesToStringErrorFormatting
    Error: "SID []byte{} convert failed reading Revision: {{err}}%!(EXTRA *errors.errorString=EOF)" should not contain "{{err}}"
    Error: "SID []byte{} convert failed reading Revision: {{err}}%!(EXTRA *errors.errorString=EOF)" should not contain "%!(EXTRA"
    Error: Target error should be in err chain

go build, go vet and go test ./helper/ldaputil/ all pass on the change.

Impact on users

Error text changes. Anything matching on the literal {{err}} or %!(EXTRA strings would need updating, though such matching seems unlikely to be deliberate.

TODO only if you're a HashiCorp employee

  • Backport Labels: If this fix needs to be backported, use the appropriate backport/ label that matches the desired release branch.
    • LTS: If this fixes a critical security vulnerability or severity 1 bug, it will also need to be backported to the current LTS versions of Vault. To ensure this, use all available enterprise labels.
  • Jira: If this change has an associated Jira, it's referenced either in the PR description, commit message, or branch name.
  • RFC: If this change has an associated RFC, please link it in the description.

PCI review checklist

  • I have documented a clear reason for, and description of, the change I am making.
  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
  • If applicable, I've documented the impact of any changes to security controls.

Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

Co-authored: 🤖 Claude Code

@drewmullen
drewmullen requested a review from a team as a code owner July 31, 2026 14:09
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vault-ui Error Error Jul 31, 2026 2:14pm

Request Review

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jul 31, 2026
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

The `vercel.json` schema validation failed with the following message: should NOT have additional property `public`

Learn More: https://vercel.com/docs/concepts/projects/project-configuration

@dosubot dosubot Bot added bug Used to indicate a potential bug helper/ldaputil labels Jul 31, 2026
@drewmullen
drewmullen requested a deployment to community-pull-request July 31, 2026 14:10 — with GitHub Actions Waiting
Six call sites built a format string containing the errwrap placeholder
`{{err}}` and passed it to fmt.Errorf with an error argument. fmt.Errorf
does not interpret `{{err}}`, and the format string had no verb to consume
the argument, so the rendered message contained both the literal placeholder
and Go's `%!(EXTRA ...)` marker:

    error connecting to host "ldaps://dc.example.com:636": {{err}}%!(EXTRA
    *ldap.Error=LDAP Result Code 200 "Network Error": dial tcp ...)

Because %w was not used, the underlying error was also not wrapped, so
errors.Is and errors.As could not reach it.

go vet does not catch this: fmt.Sprintf makes the format string
non-constant, so printf analysis is skipped.

Affects the LDAP auth method and, via ldaputil, the LDAP/AD secrets engines.

Fixes hashicorp#32063
@drewmullen

Copy link
Copy Markdown
Contributor Author

opened in enterprise repo, as requested: https://github.com/hashicorp/vault-enterprise/pull/17089

@drewmullen drewmullen closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Used to indicate a potential bug helper/ldaputil size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: sdk/helper/ldaputil: errwrap {{err}} placeholder passed to fmt.Errorf, producing malformed error messages

1 participant