Skip to content

Exit spans created inside async functions are blocking subsequent span creations #4560

@tomirantanen

Description

@tomirantanen

Describe the bug

When exit span is manually created inside async function, the following spans are not created.

The issue seems to be related to combination of creating exit span inside async function. If exitSpan option is removed from the span creation, subsequent spans are created normally. Or if the function is switched to synchronous function, then subsequent spans work as well.

Steps to reproduce the behavior:

I created a minimum example to reproduce the issue in elastic-apm-exit-span-issue.

Here are the same code snippets as in the repository above.
Not working:

const { setTimeout } = require("timers/promises");
const apm = require("elastic-apm-node").start({ serviceName: "example" });

const asyncFunction = async () => {
  const span = apm.startSpan("First span", { exitSpan: true });
  await setTimeout(5);
  span.end();
};

const run = async () => {
  apm.startTransaction("Not working transaction");
  await asyncFunction();

  const span = apm.startSpan("Second span"); // Span is not created.
  console.log({ span }); // Span is null.
  await setTimeout(5);
  span?.end();
  apm.endTransaction();
};

run();

Working as expected:

const { setTimeout } = require("timers/promises");
const apm = require("elastic-apm-node").start({ serviceName: "example" });

const notAsyncFunction = () => {
  const span = apm.startSpan("First span", { exitSpan: true });
  span.end();
};

const run = async () => {
  apm.startTransaction("Working transaction");
  notAsyncFunction();

  const span = apm.startSpan("Second span"); // Span is created normally.
  console.log({ span });
  await setTimeout(5);
  span?.end();
  apm.endTransaction();
};

run();

Expected behavior

I would expect any subsequent span creations work after creating exit span inside async function.

Environment

  • OS: OS: macOS 15.4.
  • Node.js version: 22.14.0
  • APM Server version: 8.17.4
  • Agent version: 4.11.2

How are you starting the agent?

  • Calling agent.start() directly (e.g. require('elastic-apm-node').start(...))
  • Requiring elastic-apm-node/start from within the source code
  • Starting node with -r elastic-apm-node/start

Additional context

package.json dependencies:

Click to expand
"elastic-apm-node": "4.11.2"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions