k6 Setup and Teardown Hooks Not Running Fix
In this tutorial, you'll learn about k6 setup and teardown hooks not running fix. We cover key concepts, practical examples, and best practices.
Your k6 setup or teardown function does not run — the output shows setup: 0s with zero iterations, or the data returned by setup() is undefined inside the default function. Hook functions must be exported and named correctly.
The Problem
import http from 'k6/http';
// WRONG: function not exported
function setup() {
const res = http.get('https://api.example.com/init');
return { token: res.json().token };
}
export default function (data) {
// data is undefined — setup() was never called
console.log(data.token);
}
setup: 0s
✗ data.token is undefined
The setup function is not exported — k6 cannot find it and silently skips the setup phase.
Step-by-Step Fix
1. Export the setup function
import http from 'k6/http';
export function setup() {
const res = http.get('https://api.example.com/init');
return { token: res.json().token };
}
export default function (data) {
console.log(`Token: ${data.token}`);
const res = http.get('https://api.example.com/protected', {
headers: { Authorization: `Bearer ${data.token}` },
});
}
2. Add teardown for cleanup
import http from 'k6/http';
export function setup() {
const res = http.post('https://api.example.com/session/start');
return { sessionId: res.json().session_id };
}
export default function (data) {
http.get(`https://api.example.com/data?session=${data.sessionId}`);
}
export function teardown(data) {
http.post(`https://api.example.com/session/${data.sessionId}/end`);
console.log(`Session ${data.sessionId} closed`);
}
3. Handle async setup with synchronous code
import http from 'k6/http';
export function setup() {
const login = http.post('https://api.example.com/login', '{"user":"admin","pass":"secret"}');
const token = login.json().token;
const config = http.get('https://api.example.com/config', {
headers: { Authorization: `Bearer ${token}` },
});
return {
token: token,
baseUrl: config.json().base_url,
testUsers: config.json().test_users,
};
}
export default function (data) {
const url = `${data.baseUrl}/test?user=${data.testUsers[__VU % data.testUsers.length]}`;
http.get(url, {
headers: { Authorization: `Bearer ${data.token}` },
});
}
4. Handle setup failure gracefully
import http from 'k6/http';
export function setup() {
const res = http.get('https://api.example.com/init');
if (res.status !== 200) {
console.log(`Setup failed: ${res.status}`);
return {}; // Return empty data to avoid undefined errors
}
return { config: res.json() };
}
export default function (data) {
if (!data.config) {
console.log('No config available — skipping iteration');
return;
}
http.get(data.config.endpoint);
}
5. Use environment variables in setup
import http from 'k6/http';
export function setup() {
const apiKey = __ENV.API_KEY;
const baseUrl = __ENV.BASE_URL || 'https://api.example.com';
const res = http.get(`${baseUrl}/init`, {
headers: { 'X-API-Key': apiKey },
});
return { baseUrl, data: res.json() };
}
export default function (data) {
http.get(`${data.baseUrl}/test`);
}
Expected output:
setup: 1 iterations, 0.5s
✓ Token set up correctly
✓ Session closed in teardown
Prevention Tips
- Export
setupandteardownas named functions — do not useexport default - Return an object from
setup()and use it as thedataparameter indefault - Handle setup failures gracefully by returning fallback data
- Use
teardown()for cleanup — it runs even if the test is aborted - Log setup results for debugging
Common Mistakes with lifecycle hooks
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
- Misunderstanding that
Stringis[Char]with poor performance for large text operations
These mistakes appear frequently in real-world K6 code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro