Skip to content

net/http: drop support for Transport.CancelRequest #79040

Open

Description

@neild

The long-deprecated Transport.CancelRequest function cancels an in-flight HTTP request.

This function was deprecated in Go 1.6 (February 2016) in favor of Request.Cancel (added in Go 1.5).

In Go 1.13, Request.Cancel was superseded by NewRequestWithContext, which is now the only non-deprecated request cancellation mechanism.

The documentation for CancelRequest states:

CancelRequest cannot cancel HTTP/2 requests. This may become a no-op in a future release of Go.

Supporting CancelRequest for HTTP/1 requests is quite expensive, since it requires maintaining a map of currently in-flight requests against the possibility that the user might want to cancel one. It isn't feasible to maintain cancellation state on the *Request itself, since users can and do copy in-flight requests (*newReq := *req), which causes the race detector to complain if Transport.RoundTrip mutates the input request in any way.

CancelRequest has been deprecated for a decade, is now two cancellation mechanisms out-of-date, silently fails to work for HTTP/2 requests, imposes costs on code which doesn't use it, and is documented as something which may become a no-op.

I propose that we change Transport.CancelRequest to be a no-op and log a warning once on the first call:

package http

var cancelRequestOnce sync.Once
func (*Transport) CancelRequest(req *Request) {
  cancelRequestOnce.Do(func() {
    log.Println("Use of unsupported Transport.CancelRequest. Use NewRequestWithContext instead.")
  })
}

We will also add a GODEBUG to reenable support: GODEBUG=httptransportcancelrequest=1

The GODEBUG will persist for four release cycles (standard lifetime proposed in #76163), after which we will drop support entirely.

Activity

  1. added this to the Proposal milestone on Apr 29, 2026
  2. added
    LibraryProposalIssues describing a requested change to the Go standard library or x/ libraries, but not to a tool
    on Apr 30, 2026
  3. mateusz834 commented on Apr 30, 2026

    @mateusz834
    Member
    var cancelRequestOnce sync.Once
    func (*Transport) CancelRequest(req *Request) {
      cancelRequestOnce.Do(func() {
        log.Println("Use of unsupported Transport.CancelRequest. Use NewRequestWithContext instead.")
      })
    }

    Is that log needed? Like if it is already deprecated, it could just do nothing, right? I am just uncertain whether adding an stderr log is a good idea, since making CancelRequest a noop is unlikely to break programs, but printing, might break some code.

  4. neild commented on Apr 30, 2026

    @neild
    ContributorAuthor

    Failing to cancel a request that you expect to be canceled seems like it could cause problems.

    If a program doesn't use CancelRequest, the log is harmless.

    If it does use CancelRequest (and we drop support for CancelRequest), it contains a bug; logging an error seems safer than panicking and more discoverable than silent failure.

  5. apparentlymart commented on Apr 30, 2026

    @apparentlymart

    I agree that generating an unsolicited log line is a little risky because whether to use log (vs various other possible logging strategies) is a cross-cutting decision that typically the entire program is expected to agree about.

    However, I also don't have any better ideas. I agree that silently doing nothing at all is more likely to cause real-world problems than sending a log line in a way that the rest of the program might not agree with. The unsolicited log output could potentially break CLI-based software whose caller relies on it generating output in a very specific format and fails otherwise, but that seems pretty narrow.

    I don't know whether the runtime metrics for reliance on non-default GODEBUG are widely used in the ecosystem to detect this sort of thing, but for those who do use it I hope this would be implemented in a way that means each call to CancelRequest would increment the relevant metric if the GODEBUG httptransportcancelrequest=1 were set.

  6. calebrogers066-glitch commented on Apr 30, 2026

    @calebrogers066-glitch
  7. moved this to Active in Proposalson Jun 18, 2026
  8. aclements commented on Jun 18, 2026

    @aclements
    Member

    This proposal has been added to the active column of the proposals project
    and will now be reviewed at the weekly proposal review meetings.
    — aclements for the proposal review group

  9. aclements commented on Jul 1, 2026

    @aclements
    Member

    Proposal review discussion

    • We should make the GODEBUG's default tied to the language version.
    • CancelRequest is not a major code complexity problem, but it does add a cost to every request that's essentially never necessary.
    • It is technically possible to create an "oracle" for whether CancelRequest could possibly be called. That's probably too clever and it's a solution we'd have to carry forever.
    • We don't feel strongly about the log line, one way or another. It's probably fine to drop. This proposal is predicated on the fact that there are essentially no uses of this anyway.
  10. aclements commented on Jul 8, 2026

    @aclements
    Member

    Proposal review discussion

    • Should we do a cycle of opt-in? @neild doubts that anyone would opt in, so it's not clear this would be valuable.
    • We should just do this.
    • While nobody likes the log line, in the incredibly unlikely case that your code actually trips over this, you're probably going to be happier if it said something, and there's an every smaller chance that this will trip up some log consumer. There are already a handful of places in net that log. That's probably bad, but it's precedent!
  11. aclements commented on Jul 8, 2026

    @aclements
    Member

    Based on the discussion above, this proposal seems like a likely accept.
    — aclements for the proposal review group

    The proposal is given in #79040 (comment)

  12. moved this from Active to Likely Accept in Proposalson Jul 8, 2026
  13. 6 remaining items

  14. gopherbot commented on Jul 21, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/803840 mentions this issue: net/http: make Transport.CancelRequest into a no-op

  15. added a commit that references this issue on Aug 31, 2026
    a0f3b6a
  16. prattmic commented on Sep 24, 2026

    @prattmic
    Member

    What became of the httptransportcancelrequest GODEBUG tied to the language version that controls this feature?

  17. modified the milestones: Backlog, Go1.28 on Sep 24, 2026
  18. neild commented on Sep 24, 2026

    @neild
    ContributorAuthor

    What became of the httptransportcancelrequest GODEBUG tied to the language version that controls this feature?

    Apparently I completely forgot it because I am not very smart. Will fix, sorry.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    • Status
      Accepted

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions