Skip to content

api: fix WriteRawWithContext/PatchRawWithContext premature context cancel - #32017

Open
arashzjahangiri wants to merge 1 commit into
hashicorp:mainfrom
arashzjahangiri:fix/writeraw-context-cancel
Open

api: fix WriteRawWithContext/PatchRawWithContext premature context cancel#32017
arashzjahangiri wants to merge 1 commit into
hashicorp:mainfrom
arashzjahangiri:fix/writeraw-context-cancel

Conversation

@arashzjahangiri

Copy link
Copy Markdown

Summary

WriteRawWithContext and PatchRawWithContext both route through writeRaw, which installed a withConfiguredTimeout cancel and deferred it:

func (c *Logical) writeRaw(ctx context.Context, request *Request) (*Response, error) {
    ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
    defer cancelFunc()  // fires before caller reads resp.Body

    resp, err := c.c.rawRequestWithContext(ctx, request)
    return resp, err
}

The defer fires the moment writeRaw returns, cancelling the context the response body is bound to. For small responses the body is fully buffered before the cancel matters; for large responses still streaming at read time, the caller gets a spurious context canceled even though the request succeeded server-side.

This is the exact defect fixed for the read path in #18708 and is already absent from readRawWithDataWithContext and DeleteRawWithContext, both of which call RawRequestWithContext directly.

Fix

Remove withConfiguredTimeout/defer cancelFunc() from writeRaw and delegate to RawRequestWithContext directly — identical to the pattern already used by the read/delete raw paths:

func (c *Logical) writeRaw(ctx context.Context, request *Request) (*Response, error) {
    return c.c.RawRequestWithContext(ctx, request)
}

Callers who need a timeout can set one on the context they pass in (via context.WithTimeout or context.WithDeadline).

Also adds doc comments to WriteRaw, WriteRawWithContext, PatchRaw, and PatchRawWithContext noting that raw-response functions do not apply the client-configured timeout — consistent with existing comments on the read/delete raw variants.

Testing

Added TestWriteRawWithContextBodyReadable covering both WriteRawWithContext and PatchRawWithContext: starts a real test HTTP server, calls each method, and verifies the response body is fully readable after the call returns.

Fixes #31986

…ncel

WriteRawWithContext and PatchRawWithContext both route through writeRaw,
which installed a withConfiguredTimeout cancel and deferred it:

    func (c *Logical) writeRaw(ctx context.Context, request *Request) (*Response, error) {
        ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
        defer cancelFunc()  // fires before caller reads resp.Body
        resp, err := c.c.rawRequestWithContext(ctx, request)
        return resp, err
    }

The defer fires the moment writeRaw returns, cancelling the context the
response body is bound to. For small responses the body is already fully
buffered so the race is invisible; for large responses (still streaming at
read time) the caller gets a spurious "context canceled" even though the
request succeeded server-side.

This is the same defect that was fixed for the read path in PR hashicorp#18708 and
is already absent from ReadRawWithDataWithContext and DeleteRawWithContext,
both of which call RawRequestWithContext directly without wrapping the
context in withConfiguredTimeout.

Fix: remove the withConfiguredTimeout/defer pattern from writeRaw and
delegate to RawRequestWithContext directly, matching the read/delete raw
path. Callers who need a timeout can set one on the context they pass in.

Also adds doc comments to WriteRaw, WriteRawWithContext, PatchRaw and
PatchRawWithContext noting that raw-response functions do not apply the
client-configured timeout, consistent with the existing comments on the
read/delete raw variants.

Fixes hashicorp#31986
@arashzjahangiri
arashzjahangiri requested a review from a team as a code owner June 29, 2026 10:46
@arashzjahangiri
arashzjahangiri requested a review from emoncuso June 29, 2026 10:46
@vercel

vercel Bot commented Jun 29, 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 the size:M This PR changes 30-99 lines, ignoring generated files. label Jun 29, 2026
@vercel

vercel Bot commented Jun 29, 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 Jun 29, 2026 10:46am

Request Review

@dosubot dosubot Bot added bug Used to indicate a potential bug core/api labels Jun 29, 2026
@hashicorp-cla-app

hashicorp-cla-app Bot commented Jun 29, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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 core/api size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

api: Logical.writeRaw cancels the response body's context before the caller reads it (same defect as #18658, write/patch path)

1 participant