Skip to content

[Bug]: APIRequestContext drops the cookie header passed by the caller on redirects #42840

Description

Version

1.64.0-next (main @ 04e547b); also reproduces on 1.63.0

Steps to reproduce

const http = require('http');
const { request } = require('playwright');

const server = http.createServer((req, res) => {
  console.log(req.url, req.headers.cookie);
  if (req.url === '/redirect') {
    res.writeHead(302, { location: '/final' });
    return res.end();
  }
  res.end('ok');
});

server.listen(0, '127.0.0.1', async () => {
  const base = `http://127.0.0.1:${server.address().port}`;
  const context = await request.newContext({ extraHTTPHeaders: { cookie: 'token=xyz' } });
  await context.get(base + '/redirect');
  await context.get(base + '/redirect', { headers: { cookie: 'token=abc' } });
  await context.dispose();
  server.close();
});

Expected behavior

The cookie header is sent on the redirected request as well, the same as every other header passed through headers or extraHTTPHeaders. The documentation for the headers option says: "These headers will apply to the fetched request as well as any redirects initiated by it."

/redirect token=xyz
/final token=xyz
/redirect token=abc
/final token=abc

Actual behavior

The redirect target receives no cookie at all:

/redirect token=xyz
/final undefined
/redirect token=abc
/final undefined

When the context cookie store has cookies for the target URL, those replace the explicit header on the redirected request instead.

Additional context

_sendRequest in packages/playwright-core/src/server/fetch.ts adds cookies from the context store to options.headers unless a cookie header is already present, so an explicit header wins on the first hop. The redirect path then removes cookie from the headers unconditionally before following the redirect, because it cannot tell the caller's header apart from the ones it added itself. The next hop only gets whatever the cookie store holds for the new URL.

This affects playwright.request.newContext(), context.request and route.fetch(). A common case is a standalone request context with a session cookie copied from a browser and an endpoint that redirects, for example /login to /dashboard or /api/resource to /api/resource/: the second request goes out unauthenticated, and the failure is silent.

I intend to work on this and will send a PR.

Environment

- Operating System: Windows 11
- Node.js: 22.17.0
- Playwright: main @ 04e547b

Activity

  1. yury-s commented on Oct 2, 2026

    @yury-s
    Member

    We decided not to change this, so existing users won't break. An explicit Cookie header still applies only to the first request. Redirects after that take their cookies from the context's cookie jar. To make this easier to work with, APIRequestContext now has cookie methods, so you can put cookies in the jar directly and they'll be sent on every hop, redirects included.

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

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions