Skip to main content

How to Resolve the Jest Error: "Exceeded timeout of 5000 ms" in JavaScript

The error message Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout is one of the most common issues when writing asynchronous tests in Jest. It means that your test started an async operation but did not finish within the default 5-second time limit.

This guide will explain the two main causes of this error: a test that is genuinely slow and a test that is written incorrectly. You will learn how to increase the timeout and, more importantly, how to correctly write async tests with async/await and the older done callback.

The Core Problem: Asynchronous Tests Taking Too Long

Jest is designed to run tests quickly. By default, if a single test takes longer than 5 seconds (5000 ms), Jest will automatically fail it with a timeout error. This prevents a broken test from hanging your entire test suite.

This error is most common when you are testing code that involves:

  • Network requests (fetch, axios)
  • Database queries
  • Complex calculations
  • Code that uses setTimeout or setInterval

The following test simulates a long-running operation that takes 6 seconds. It will fail because it exceeds the default 5-second timeout.

// This test will fail by default
it('should resolve with the correct data', async () => {
const promise = new Promise(resolve => {
setTimeout(() => resolve('some data'), 6000); // Resolves after 6 seconds
});

const data = await promise;
expect(data).toBe('some data');
});

Error Output:

Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.

Solution 1: Increasing the Jest Timeout

If your test is expected to take longer than 5 seconds, the solution is to increase the timeout.

For a Single Test

You can provide a third argument to the test() (or it()) function, which is the timeout in milliseconds for that specific test.

Solution:

it('should resolve with the correct data', async () => {
const promise = new Promise(resolve => {
setTimeout(() => resolve('some data'), 6000);
});

const data = await promise;
expect(data).toBe('some data');
}, 10000); // 10,000 ms = 10 seconds timeout for this test
note

This is the best approach when only a few specific tests are slow.

For All Tests (Global Configuration)

If most of your tests are slow (e.g., in an end-to-end test suite), you can increase the timeout globally in your Jest configuration file.

jest.config.js:

module.exports = {
// The default timeout for all tests, in milliseconds.
testTimeout: 30000, // 30 seconds
};
note

This sets the new default for your entire project, so you don't have to specify it on each test.

Solution 2 (Common Mistake): Correctly Handling Async Test Logic

Often, a timeout error is not because the test is slow, but because Jest doesn't know when the test has finished. This happens when you mix up different styles of async test code.

This is the modern and best practice. When you mark the test function as async, Jest automatically waits for the promise returned by the function to resolve.

Solution:

it('should work with async/await', async () => {
const data = await someAsyncFunction();
expect(data).toBe('expected value');
});

Using the done Callback

This is an older pattern. If your test function accepts an argument (conventionally named done), Jest will wait until that done() callback is explicitly called before finishing the test.

Solution:

it('should work with a done callback', (done) => {
someAsyncFunction().then(data => {
expect(data).toBe('expected value');
done(); // You must call done() to signal completion
});
});

If you forget to call done(), the test will always time out.

The Pitfall: Mixing async/await with done

You cannot use both async/await and a done callback in the same test. Doing so will cause Jest to produce a timeout error because it doesn't know which signal to wait for.

Example of code with errors:

// INCORRECT: This test will always time out.
it('should not mix async and done', async (done) => {
const data = await someAsyncFunction();
expect(data).toBe('expected value');
done();
});

Solution: Choose one pattern and stick with it. For modern JavaScript, async/await is strongly preferred for its readability. Simply remove the done argument.

// CORRECTED: Remove the 'done' argument
it('should use only async/await', async () => {
const data = await someAsyncFunction();
expect(data).toBe('expected value');
});

Conclusion

The "Exceeded timeout" error in Jest almost always points to one of two issues:

  1. The test is legitimately slow: If an asynchronous operation is expected to take longer than 5 seconds, increase the timeout either for the specific test(..., 10000) or globally in jest.config.js.
  2. The test is written incorrectly: If your test finishes quickly but still times out, ensure you are not accidentally mixing async/await with a done callback. Remove the done argument when using async/await.

By diagnosing which of these two problems you have, you can quickly fix the timeout error and ensure your asynchronous tests run reliably.