# Forcibly closed connection causing test to fail

**URL:** <https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897>\
**Category:** k6-browser\
**Created:** [June 1, 2022, 1:00pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897 "2022-06-01T13:00:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 1:00pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/1 "2022-06-01T13:00:45Z")

</div>

Hi,  
I have a test script that does a few page changes using client javascript calls but it constantly crashes with: “An existing connection was forcibly closed”

I cannot seem to understand why k6 breaks, maybe you have some ideas?  
It seems like K6 is perhaps timing out or interpreting some failure to load woffs as a failure to load the page?

A second problem is that once it closes it context there is no way for me to measure that and take action. Preferably I want to keep the same context as to not download to much data while testing.

Any ideas?

The data and log is from a short moc run over only 60s in order to make replicating easier.

The complete log is (URL blanked out):

```auto
  execution: local
     script: scripts\moctest.js
     output: -

  scenarios: (100.00%) 1 scenario, 2 max VUs, 1m50s max duration (incl. graceful stop):
           * default: Up to 2 looping VUs for 1m20s over 3 stages (gracefulRampDown: 30s, gracefulStop: 30s)

INFO[0002] :: Running setup source=console
INFO[0002] [1]:: requests: 5 source=console
INFO[0002] [1]request time: 9000 source=console
INFO[0002] [1]:: sleeping for 8.996s source=console
INFO[0011] [1]:: create context source=console
INFO[0012] [2]:: requests: 2 source=console
INFO[0013] [2]request time: 58000 source=console
INFO[0013] [2]:: sleeping for 57.223s source=console
INFO[0013] :: goto: https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx?login=1&pageid=0 source=console
INFO[0015] [1]=====================> 1 source=console
INFO[0016] [1]request time: 27000 source=console
INFO[0016] [1]:: sleeping for 13.539s source=console
WARN[0017] The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu browser_source=other line_number=233 source=browser url="https://MY.DOMAIN.com/pnt_fix_prod/include/amd/Highcharts%209.0.1.0/modules/sonification.js"
INFO[0029] [1]:: navigate to subl2g0tci1tglh9jo6j29 source=console
INFO[0029] :: goto pageid: subl2g0tci1tglh9jo6j29 source=console
WARN[0031] url:https://MY.DOMAIN.com/pnt_fix_prod/themes/X/fonts/fontawesome/webfonts/fa-regular-400.woff2 method:GET err:error fetching response body: No data found for resource with given identifier (-32000) category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=65
WARN[0031] url:https://MY.DOMAIN.com/pnt_fix_prod/themes/X/fonts/fontawesome/webfonts/fa-solid-900.woff2 method:GET err:error fetching response body: No data found for resource with given identifier (-32000) category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=65
INFO[0031] [1]=====================> 2 source=console
INFO[0031] [1]request time: 35000 source=console
INFO[0031] [1]:: sleeping for 5.888s source=console
INFO[0037] [1]:: navigate to searchpage source=console
INFO[0037] :: goto pageid: searchpage source=console
WARN[0039] url:https://MY.DOMAIN.com/pnt_fix_prod/themes/X/fonts/fontawesome/webfonts/fa-regular-400.woff2 method:GET err:error fetching response body: No data found for resource with given identifier (-32000) category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=65
WARN[0039] url:https://MY.DOMAIN.com/pnt_fix_prod/themes/X/fonts/fontawesome/webfonts/fa-solid-900.woff2 method:GET err:error fetching response body: No data found for resource with given identifier (-32000) category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=65
INFO[0039] [1]=====================> 3 source=console
INFO[0039] [1]request time: 46000 source=console
INFO[0039] [1]:: sleeping for 8.915s source=console
ERRO[0041] err:read tcp 127.0.0.1:64886->127.0.0.1:64885: wsarecv: An existing connection was forcibly closed by the remote host. category="Connection:handleIOError" elapsed="0 ms" goroutine=45
INFO[0048] [1]:: navigate to subl2g0tci1tglh9jo6j29 source=console
INFO[0048] :: goto pageid: subl2g0tci1tglh9jo6j29 source=console
ERRO[0049] wsURL:"ws://127.0.0.1:64885/devtools/browser/eeb495d7-382e-444b-b125-0bf70928cc15" sid:41EACE412790FCD6DC32C1F7DA32EBD7 err:context canceled category="Connection:send:<-c.ctx.Done()" elapsed="7996 ms" goroutine=34
ERRO[0049] [1]:: ERROR :: error calling evaluate: frame cannot evaluate: cannot call function on expression ("pid => _W.GoToPageId(pid)\n//# sourceURL= __xk6_browser_evaluation_script__ \n") in execution context (7) in frame (1F1969461A362C929196BA1CD6A65D06) with session (41EACE412790FCD6DC32C1F7DA32EBD7): context canceled source=console
INFO[0049] [1]:: closing page source=console
INFO[0049] [1]request time: 60000 source=console
INFO[0049] [1]:: sleeping for 12.961s source=console
INFO[0062] [1]:: create new page source=console
ERRO[0062] [1]:: ERROR :: newPageInContext: missing browser context: 502999377E10F37D948649892A8E6C90 source=console
INFO[0062] [1]:: closing page source=console
INFO[0062] [1]request time: 9000 source=console
INFO[0062] [1]:: create new page source=console
ERRO[0062] [1]:: ERROR :: newPageInContext: missing browser context: 502999377E10F37D948649892A8E6C90 source=console
INFO[0062] [1]:: closing page source=console
ERRO[0062] wsURL:"ws://127.0.0.1:64885/devtools/browser/eeb495d7-382e-444b-b125-0bf70928cc15" sid: err:context canceled category="Connection:send:<-ctx.Done()" elapsed="13032 ms" goroutine=34
ERRO[0062] cannot dispose browser context: unable to dispose browser context *target.DisposeBrowserContextParams: context canceled
        at reflect.methodValueCall (native)
        at file:///C:/Program%20Files/k6/scripts/moctest.js:128:6(378)
        at native executor=ramping-vus scenario=default source=stacktrace
INFO[0062] [1]:: requests: 5 source=console
INFO[0062] [1]request time: 9000 source=console
INFO[0062] [1]:: sleeping for 8.988s source=console
INFO[0071] [2]:: create context source=console
INFO[0071] :: goto: https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx?login=1&pageid=0 source=console
INFO[0071] [1]:: create context source=console
INFO[0073] [2]=====================> 1 source=console
INFO[0074] [2]request time: 62000 source=console
INFO[0073] :: goto: https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx?login=1&pageid=0 source=console
WARN[0074] url:https://MY.DOMAIN.com/pnt_fix_prod/include/amd/Highcharts%209.0.1.0/highcharts.js method:GET err:error fetching response body: context canceled category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=1754

```

And the complete moc script:

```auto
import { SharedArray } from 'k6/data';
import { sleep } from "k6";
import launcher from "k6/x/browser";
import { vu, test } from "k6/execution";

const baseUrl = 'https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx'
const startPages = ['0']
const pages = ['0','searchpage','c1','subl2g0tci1tglh9jo6j29']
const jitter = 10 // 1800 // seconds
const cooldown = '10s'
const duration = 60 // 3600 // seconds
const headless = true
const sod_start = 13*24*60*60*1000+10*60*60*1000 + 50000 // 10:00
const t0 = sod_start
const t1 = t0 + duration*1000 // +1h
const dryrun = false

const vu_reqs = new SharedArray('reqs', function () {
  return [
    [{"t":9000,"session":"t0_159","islast":false},{"t":27000,"session":"t0_159","islast":false},{"t":35000,"session":"t0_159","islast":false},{"t":46000,"session":"t0_159","islast":false},{"t":60000,"session":"t0_159","islast":false}],
    [{"t":58000,"session":"t0_25","islast":false},{"t":62000,"session":"t0_25","islast":false}]
  ]
})

export let options = {
  stages: [
      { target: vu_reqs.length, duration: dryrun ? 1 : jitter + "s" },
      { target: vu_reqs.length, duration: dryrun ? 1 : duration + "s" },
      { target: 0, duration: dryrun ? 1 : cooldown }
  ],
  thresholds: {
      "http_req_duration": ["p(95)<500"],
      "http_req_duration{staticAsset:yes}": ["p(99)<250"],
  },
}

function start(config = {headless: true}) {
  const browser = launcher.launch('chromium', config)
  const context = browser.newContext()
  const page = context.newPage()
  return {browser, context, page}
}
function openPage(ctx) {
  ctx.page = ctx.context.newPage()
  return ctx
}
function setUrl(ctx, url) {
  console.log(":: goto: " + url)
  ctx.page.goto(url, { waitUntil: 'load' })
}
function gotoPageId(ctx, pageId) {
  console.log(":: goto pageid: " + pageId)
  sleep(1) // Just for more safety
  ctx.page.evaluate((pid) => _W.GoToPageId(pid), pageId)
  sleep(1) // Just for more safety
  ctx.page.waitForLoadState('load')
}

let trueStartTime = Date.now()

export function setup() {
  console.log(":: Running setup")
  if(dryrun) console.warn("THIS IS A DRY RUN")
  trueStartTime = Date.now()
}

export default function(data) {
  if(dryrun) return

  let startTime = Date.now()
  let vuRampup = jitter - ((startTime - trueStartTime) / 1000)
  let counter = 0
  let ctx = null

  const reqs = vu_reqs[vu.idInTest - 1]
  console.log("[" + vu.idInTest + "]" + ':: requests: ' + reqs.length)
  const reqsCount = reqs.length
  let isClosed = true
  for(let i = 0; i < reqsCount; i++ ) {
    const req = reqs[i]
    console.log("[" + vu.idInTest + "]" + 'request time: ' + req.t)
    let now = Date.now()
    let t = now - startTime

    if((t / 1000) >= vuRampup + duration) {
      test.abort("[" + vu.idInTest + "]" + "==> TIME IS UP 1!")
      break;
    }

    if (req.t > t) {
      const sleepTime = req.t - t
      if(((t + sleepTime) / 1000) >= vuRampup + duration) {
        console.log("[" + vu.idInTest + "]" + "==> Test duration is up! Exiting.", t, sleepTime, vuRampup, duration)
        break;
      }
      console.log("[" + vu.idInTest + "]" + ":: sleeping for " + ((req.t - t) / 1000) + "s")
      sleep(sleepTime / 1000)
    }
    try {
      if (!ctx) {
        console.log("[" + vu.idInTest + "]" + ":: create context")
        ctx = start({headless})
        setUrl(ctx, baseUrl + '?login=1&pageid=' + startPages[((Math.random() * startPages.length) | 0)]) // Start at start page
        isClosed = false
      } else {
        if (ctx && isClosed) {
          console.log("[" + vu.idInTest + "]" + ":: create new page")
          ctx = openPage(ctx)
          setUrl(ctx, baseUrl + '?login=1&pageid=' + startPages[((Math.random() * startPages.length) | 0)]) // Start at start page
          isClosed = false
        } else {
          let pageId = pages[(Math.random() * pages.length) | 0]
          console.log("[" + vu.idInTest + "]" + ":: navigate to " + pageId)
          gotoPageId(ctx, pageId) // Go to random page
          isClosed = false
        }
      }
      console.log("[" + vu.idInTest + "]" + "=====================> " + (++counter))
    } catch (err) {
      console.error("[" + vu.idInTest + "]" + ":: ERROR :: " + err)
      console.log("[" + vu.idInTest + "]" + ":: closing page")
      ctx.page.close()
      isClosed = true
      if(i === reqsCount - 1) i = -1;
      continue;
    }
    if(req.islast) {
      console.log("[" + vu.idInTest + "]" + ":: is last in session, closing page")
      if(ctx) {
        ctx.page.close()
        isClosed = true
      }
      break;
    }
    if(i === reqsCount - 1) i = -1;
  
  }

  if(ctx) {
    if(!ctx.page.isClosed) {
      ctx.page.close()
    }
    if(ctx.browser) {
      ctx.browser.close()
      ctx.browser = null
    }
  }
  sleep(jitter + duration - ((Date.now() - trueStartTime) / 1000))
  if((jitter + duration - ((Date.now() - trueStartTime) / 1000)) <= 0) {
    test.abort("[" + vu.idInTest + "]" + "==> TIME IS UP 2!")
  }
}

```

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 1, 2022, 1:41pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/3 "2022-06-01T13:41:29Z")

</div>

Hi @Goodgive,

It seems like the browser context error starts happening after getting the following error:

> [@Goodgive](#):
>
> ```auto
> ERRO[0041] err:read tcp 127.0.0.1:64886->127.0.0.1:64885: wsarecv: An existing connection was forcibly closed by the remote host. category="Connection:handleIOError" elapsed="0 ms" goroutine=45
> 
> ```

The first thing that comes to mind is that the remote server somehow refuses connections.

There is another error related to `_W.GoToPageId` method that says the function does not exist on the page. It’s probably because the connection to the browser is gone. Then again, maybe you could try waiting for the function first using [waitForFunction](https://github.com/grafana/xk6-browser/pull/294). This probably won’t solve the problem as I believe the error is happening because of the remote host somehow.

Please let me know how it goes.

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 2:01pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/4 "2022-06-01T14:01:53Z")

</div>

I did as you asked and replaced:  
`ctx.page.evaluate((pid) => _W.GoToPageId(pid), pageId)`  
with  
`ctx.page.waitForFunction((pid) => _W.GoToPageId(pid), pageId)`

But it seems that wait for function does not pass the parameter along as it should as I get this error now.

```auto
ERRO[0029] Failed to load resource: the server responded with a status of 500 (Internal Server Error) browser_source=network line_number=0 source=browser stacktrace="<nil>" url="https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx?pageid=undefined&wb_sessionid=d698acbd-7ef3-4a85-bc87-2ba2f30af34a&wb_nonce=f4f67da9-90ff-4c57-b305-055a4cbc3bcf&__timestamp=1654091690615"

```

where `pageid=undefined` causes server error.

Am I using it wrong or is there a bug there?  
//J

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 2:25pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/5 "2022-06-01T14:25:41Z")

</div>

Hello again,  
I notice that nomatter the timing of my requests it always dies **30s** after the first request.  
So someone is timing out.  
Of course I have tried calling the same addresses manually in Chrome and there is no error or timeout there that I can see. Also the other navigations go through and pages do change and load in the test, until the connection dies.

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 1, 2022, 2:40pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/6 "2022-06-01T14:40:00Z")

</div>

Hmm, that’s interesting because our default timeout is 30 seconds! Could you try increasing the browser context navigation and default timeouts using `setDefaultNavigationTimeout` and `setDefaultTimeout` using the browser context object?

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 2:51pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/7 "2022-06-01T14:51:57Z")

</div>

I changed the start function to:

```auto
function start(config = {headless: true}) {
  const browser = launcher.launch('chromium', config)
  const context = browser.newContext()
  context.setDefaultNavigationTimeout(60)
  context.setDefaultTimeout(60)
  const page = context.newPage()
  return {browser, context, page}
}

```

But it still timesout after 30.

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 1, 2022, 2:52pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/8 "2022-06-01T14:52:19Z")

</div>

I also discussed this with my coworker, who suggested that `waitForLoadState('load')` could be timing out. If you’re expecting navigation after the `evaluate()` call, `waitForSelector()` would probably work better. And lastly, we don’t recommend using `sleep` calls in the scripts (as sleeping might cause synchronization problems in xk6-browser and the Chrome browser internals).

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 2:57pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/9 "2022-06-01T14:57:31Z")

</div>

Well I expect navigation to happen after all the calls. First call is setting the URL and the rest make a JS call that changes the page. And with headless = false, I see the page load as well.  
Also it seems that the timeout the happens in the first call which is using goto with waitUntil:

```auto
function setUrl(ctx, url) {
  console.log(":: goto: " + url)
  ctx.page.goto(url, { waitUntil: 'load' })
}

```

What should I use if I need to wait some seconds before I navigate in order to simulate a flow of requests previously recorded?

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 3:02pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/10 "2022-06-01T15:02:41Z")

</div>

Hi,  
The same timeout happens even with just 1 request, by changing the request array to:

```auto
const vu_reqs = new SharedArray('reqs', function () {
  return [
    [{"t":2000,"session":"t0_159","islast":false},{"t":40000,"session":"t0_159","islast":false}]
  ]
})

```

In other words there is only one `page.goto(url, { waitUntil: 'load' })` call and no other actions before the crash.

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 1, 2022, 3:05pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/11 "2022-06-01T15:05:38Z")

</div>

After going to a page, you might try to wait for an element using `waitForSelector` to wait until it’s loaded by checking whether a necessary element is on the page.

We don’t currently offer a way to wait ☹ The philosophy we follow is similar to what is explained in [this article](https://dev.to/checkly/avoiding-hard-waits-in-playwright-and-puppeteer-272). What happens if you don’t use `sleep` at all?

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 3:09pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/12 "2022-06-01T15:09:57Z")

</div>

I will test not sleeping, but this would kind of ruin the usecase since I cannot control the amount of request per time unit then.

I simplified the code more.  
Logs are the same.  
Basically it seems as if the VU is timing out?

```auto
INFO[0000] :: Running setup source=console
INFO[0002] :: goto: https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx?login=1&pageid=0 source=console
WARN[0004] The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu browser_source=other line_number=233 source=browser url="https://MY.DOMAIN.com/pnt_fix_prod/include/amd/Highcharts%209.0.1.0/modules/sonification.js"
ERRO[0030] err:read tcp 127.0.0.1:64362->127.0.0.1:64361: wsarecv: An existing connection was forcibly closed by the remote host. category="Connection:handleIOError" elapsed="0 ms" goroutine=49

```

```auto
import { SharedArray } from 'k6/data';
import { sleep } from "k6";
import launcher from "k6/x/browser";
import { vu, test } from "k6/execution";

const baseUrl = 'https://MY.DOMAIN.com/pnt_fix_prod/Default.aspx'
const startPages = ['0']
const pages = ['0','searchpage','c1','subl2g0tci1tglh9jo6j29']
const jitter = 0 // 1800 // seconds
const cooldown = '10s'
const duration = 60 // 3600 // seconds
const headless = true
const sod_start = 13*24*60*60*1000+10*60*60*1000 + 50000 // 10:00
const t0 = sod_start
const t1 = t0 + duration*1000 // +1h
const dryrun = false

const vu_reqs = new SharedArray('reqs', function () {
  return [
    [{"t":2000,"session":"t0_159","islast":false},{"t":40000,"session":"t0_159","islast":false}]
  ]
})

export let options = {
  stages: [
      { target: vu_reqs.length, duration: dryrun ? 1 : duration + "s" }
  ],
  thresholds: {
      "http_req_duration": ["p(95)<500"],
      "http_req_duration{staticAsset:yes}": ["p(99)<250"],
  },
}

function start(config = {headless: true}) {
  const browser = launcher.launch('chromium', config)
  const context = browser.newContext()
  context.setDefaultNavigationTimeout(60)
  context.setDefaultTimeout(60)
  const page = context.newPage()
  return {browser, context, page}
}

function setUrl(ctx, url) {
  console.log(":: goto: " + url)
  ctx.page.goto(url, { waitUntil: 'load' })
}

let trueStartTime = Date.now()

export function setup() {
  console.log(":: Running setup")
  if(dryrun) console.warn("THIS IS A DRY RUN")
  trueStartTime = Date.now()
}

export default function(data) {
  let ctx = start({headless})
  setUrl(ctx, baseUrl + '?login=1&pageid=' + startPages[((Math.random() * startPages.length) | 0)]) // Start at start page

  sleep(40)

  if(ctx) {
    if(!ctx.page.isClosed) {
      ctx.page.close()
    }
    if(ctx.browser) {
      ctx.browser.close()
      ctx.browser = null
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 1, 2022, 3:15pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/13 "2022-06-01T15:15:12Z")

</div>

Hmm, there is another error there (`The AudioContext was not allowed to start`). You might try to grant audio permission to the browser context. Could you take a look at [this issue](https://github.com/grafana/xk6-browser/issues/313)? Here’s an [example](https://github.com/grafana/xk6-browser/blob/main/examples/grant_permission.js). You need to use xk6-browser from our `main` branch since we have not released the fix yet.

It might help if you can provide us with a page where we can replicate the problematic behavior.

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 3:30pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/14 "2022-06-01T15:30:30Z")

</div>

If I just remove all waits and made it start on a different page where the audiocontext is not used the function looks like this:

```auto
export default function(data) {
  let ctx = start({headless})
  ctx.page.goto(baseUrl + '?login=1&pageid=' + startPages[((Math.random() * startPages.length) | 0)], { waitUntil: 'load' }) // Start at start page

  ctx.page.close()
  ctx.browser.close()
}

```

But it seem to fail to close it nicely:

```auto
INFO[0000] :: Running setup source=console
WARN[0002] url:https://MY.DOMAIN.com/pnt_fix_prod/themes/X/fonts/fonts.css?v=6.0.8175.25369 method:GET err:error fetching response body: context canceled category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=57
WARN[0004] url:https://MY.DOMAIN.com/pnt_fix_prod/themes/X/fonts/fonts.css?v=6.0.8175.25369 method:GET err:error fetching response body: context canceled category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=500
ERRO[0004] err:websocket: close 1006 (abnormal closure): unexpected EOF category="Connection:handleIOError" elapsed="0 ms" goroutine=390

```

And why are the font downloads failing? Do you have a max document size?

Also, the sleep() command is used in the K6 examples, and it does seem to work and wait fine.  
Maybe you have a 30s timeout on the VUs?

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 1, 2022, 3:51pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/15 "2022-06-01T15:51:25Z")

</div>

Hi,  
Simple repo:

```auto
export default function(data) {
  const browser = launcher.launch('chromium', {headless: true})
  const context = browser.newContext({
  })
  context.setDefaultNavigationTimeout(60)
  context.setDefaultTimeout(60)
  const page = context.newPage()
  page.goto('https://www.google.com/', { waitUntil: 'load' }) // Start at start page
  sleep(40)
  page.close()
  browser.close()
}

```

Both errors are there. The timeout after 30s…

```auto
INFO[0000] :: Running setup source=console
ERRO[0030] err:read tcp 127.0.0.1:51033->127.0.0.1:51032: wsarecv: An existing connection was forcibly closed by the remote host. category="Connection:handleIOError" elapsed="0 ms" goroutine=46

```

and the unclean close if you remove the sleep.

```auto
INFO[0000] :: Running setup source=console
WARN[0002] url:https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png method:GET err:error fetching response body: context canceled category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=71
WARN[0002] url:https://fonts.gstatic.com/s/i/productlogos/googleg/v6/24px.svg method:GET err:error fetching response body: context canceled category="Response:bodySize:fetchBody" elapsed="0 ms" goroutine=71
ERRO[0002] err:write tcp 127.0.0.1:51279->127.0.0.1:51278: wsasend: An established connection was aborted by the software in your host machine. category="Connection:handleIOError" elapsed="0 ms" goroutine=44

```

EDIT: Made the code simpler  
EDIT2: This is using release 0.3  
EDIT3: On Windows Server 2016 Data Center

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 2, 2022, 12:35pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/16 "2022-06-02T12:35:48Z")

</div>

@inanc Is it at all reproducable on your side with the minimal example?

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 2, 2022, 12:56pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/17 "2022-06-02T12:56:58Z")

</div>

I’ll try working on this tomorrow, and let you know 🙂 Thanks for the example!

---

<div class="post-metadata">

**Author:** ![inancgumus](https://sea2.discourse-cdn.com/grafana/user_avatar/community.grafana.com/inancgumus/32/34670_2.png) [@inancgumus](https://community.grafana.com/u/inancgumus)\
**Post date:** [June 3, 2022, 12:12pm UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/18 "2022-06-03T12:12:58Z")

</div>

Hi @Goodgive,

I tried your script and did not get the “forcibly closed” error ☹ I’m suspicious of your network settings 🤔 Could you check?

Could you also run the script with the `XK6_BROWSER_LOG=trace` environment variable?

Thanks

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 7, 2022, 8:47am UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/19 "2022-06-07T08:47:14Z")

</div>

I ran the test locally on my own machine and it does work fine there.  
On the DataCenter Server I get the following trace (a subset):

```auto
DEBU[0028] running thresholds component=metrics-engine metric_name="http_req_duration{staticAsset:yes}"
DEBU[0030] running thresholds component=metrics-engine metric_name=http_req_duration
DEBU[0030] running thresholds component=metrics-engine metric_name="http_req_duration{staticAsset:yes}"
DEBU[0030] wsURL:"ws://127.0.0.1:65294/devtools/browser/470c15b2-c297-461e-a420-bbbf7eb9a338" ioErr:read tcp 127.0.0.1:65295->127.0.0.1:65294: wsarecv: An existing connection was forcibly closed by the remote host. category="Connection:recvLoop" elapsed="19193 ms" goroutine=51
ERRO[0030] err:read tcp 127.0.0.1:65295->127.0.0.1:65294: wsarecv: An existing connection was forcibly closed by the remote host. category="Connection:handleIOError" elapsed="41 ms" goroutine=51
DEBU[0030] code:1001 category="Connection:handleIOError:c.closeCh <-" elapsed="3 ms" goroutine=51
DEBU[0030] wsURL:"ws://127.0.0.1:65294/devtools/browser/470c15b2-c297-461e-a420-bbbf7eb9a338" code:1001 category="Connection:sendLoop:<-c.closeCh" elapsed="9 ms" goroutine=52
DEBU[0030] code:1001 category="Connection:closeConnection" elapsed="6 ms" goroutine=52
DEBU[0030] sid:EA6E0382352DBFB3E7CA4984518878AB tid:BDCB2C951A04997FB5BE172B59A3587E category="Session:close" elapsed="6 ms" goroutine=52
DEBU[0030] sid:F909FE0D2F82C3777B70EAF0BCC6B683 tid:0E295D7D8838B74BC238F53179DF2D70 category="Session:close" elapsed="15 ms" goroutine=52
DEBU[0030] sid:EA6E0382352DBFB3E7CA4984518878AB tid:BDCB2C951A04997FB5BE172B59A3587E category="Session:readLoop:<-s.done" elapsed="6 ms" goroutine=59
DEBU[0030] sid:EA6E0382352DBFB3E7CA4984518878AB tid:BDCB2C951A04997FB5BE172B59A3587E category="FrameSession:initEvents:go:session.done" elapsed="5 ms" goroutine=70
DEBU[0030] sid:EA6E0382352DBFB3E7CA4984518878AB tid:BDCB2C951A04997FB5BE172B59A3587E category="NewFrameSession:initEvents:go:return" elapsed="6 ms" goroutine=70
DEBU[0030] sid:F909FE0D2F82C3777B70EAF0BCC6B683 tid:0E295D7D8838B74BC238F53179DF2D70 category="FrameSession:initEvents:go:session.done" elapsed="4 ms" goroutine=143
DEBU[0030] sid:F909FE0D2F82C3777B70EAF0BCC6B683 tid:0E295D7D8838B74BC238F53179DF2D70 category="Session:readLoop:<-s.done" elapsed="5 ms" goroutine=64
DEBU[0030] category="Browser:initEvents:EventConnectionClose" elapsed="3 ms" goroutine=54
DEBU[0030] sid:F909FE0D2F82C3777B70EAF0BCC6B683 tid:0E295D7D8838B74BC238F53179DF2D70 category="NewFrameSession:initEvents:go:return" elapsed="6 ms" goroutine=143
DEBU[0032] running thresholds component=metrics-engine metric_name=http_req_duration
DEBU[0032] running thresholds component=metrics-engine metric_name="http_req_duration{staticAsset:yes}"

```

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 7, 2022, 8:50am UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/20 "2022-06-07T08:50:55Z")

</div>

The full script I ran on both machines.

```auto
import { sleep } from "k6";
import launcher from "k6/x/browser";

export let options = {
  stages: [
    { target: 1, duration: '60s' }
  ],
  thresholds: {
      "http_req_duration": ["p(95)<500"],
      "http_req_duration{staticAsset:yes}": ["p(99)<250"],
  },
}

export default function(data) {
  const browser = launcher.launch('chromium', {headless: true})
  const context = browser.newContext({
  })
  context.setDefaultNavigationTimeout(60)
  context.setDefaultTimeout(60)
  const page = context.newPage()
  console.log("goto page")
  page.goto('https://www.google.com/', { waitUntil: 'load' }) // Start at start page
  console.log("sleep")
  sleep(40)
  page.close()
  browser.close()
}

```

---

<div class="post-metadata">

**Author:** ![Goodgive](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@Goodgive](https://community.grafana.com/u/Goodgive)\
**Post date:** [June 7, 2022, 10:26am UTC](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897/21 "2022-06-07T10:26:51Z")

</div>

It would be helpfull if K6 could output a bit more about the reason?  
Does it have something to do with TLS versioning perhaps?  
Is it the ws connection to devtools that closes the connection and devtools is the “remote host” or is it the remote site that does it?

[Next page](https://community.grafana.com/t/forcibly-closed-connection-causing-test-to-fail/96897.md?page=2)
