# Unexpected Leak

**URL:** <https://ziggit.dev/t/unexpected-leak/16208>\
**Category:** Help\
**Tags:** memory-management\
**Created:** [June 16, 2026, 6:32pm UTC](https://ziggit.dev/t/unexpected-leak/16208 "2026-06-16T18:32:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mashrafidipto](https://ziggit.dev/user_avatar/ziggit.dev/mashrafidipto/32/6673_2.png) [@Mashrafidipto](https://ziggit.dev/u/Mashrafidipto)\
**Post date:** [June 16, 2026, 6:32pm UTC](https://ziggit.dev/t/unexpected-leak/16208/1 "2026-06-16T18:32:53Z")

</div>

I am trying to write this program but a unexpected memory leak occurs.

```zig
const std = @import("std");
const Io = std.Io;

pub fn main(init: std.process.Init) !void {
    const gpa = init.gpa;

    var client = std.http.Client{
        .allocator = gpa,
        .io = init.io,
    };

    var redirect_buffer: [4096]u8 = undefined;

    var response_body = try std.ArrayList(u8).initCapacity(gpa, 4096);
    var response_writer = Io.Writer.fromArrayList(&response_body);

    defer response_body.deinit(gpa);

    defer client.deinit(); // <- Here

    const response = try client.fetch(.{
        .location = .{
            .url = "https://jsonplaceholder.typicode.com/posts/1",
        },
        .method = .GET,
        .redirect_buffer = &redirect_buffer,
        .response_writer = &response_writer,
    });

    if (response.status == .ok) {
        std.debug.print("Stored Input:\n{s}\n", .{response_body.items});
    } else {
        std.debug.print("HTTP Error Status: {}\n", .{response.status});
    }
}

```

For some reason the leak only happens when I am trying to use the arraylist but the error occurs in client.deinit() .  
From lldb I get `TlsInitializationFailed` if it is any help .  
here is the error I get

```zig
error(DebugAllocator): memory address 0x7f9d2f061000 leaked:
/home/usr/Applications/zig-0.16.0/lib/std/array_list.zig:1235:56: 0x15b68f7 in ensureTotalCapacityPrecise (std.zig)
                const new_memory = try gpa.alignedAlloc(T, alignment, new_capacity);
                                                       ^
/home/usr/Applications/zig-0.16.0/lib/std/array_list.zig:606:48: 0x15b9907 in initCapacity (std.zig)
            try self.ensureTotalCapacityPrecise(gpa, num);
                                               ^
/home/usr/Documents/zig/no1/src/main.zig:15:59: 0x11fa368 in main (main.zig)
    var response_body = try std.ArrayList(u8).initCapacity(gpa, 4096);
                                                          ^
/home/rmashrafi/Applications/zig-0.16.0/lib/std/start.zig:737:30: 0x11fb29e in callMain (std.zig)
    return wrapMain(root.main(.{
                             ^
/home/usr/Applications/zig-0.16.0/lib/std/start.zig:190:5: 0x11fa0e1 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^

```

---

<div class="post-metadata">

**Author:** ![rosew0od](https://ziggit.dev/user_avatar/ziggit.dev/rosew0od/32/7663_2.png) [@rosew0od](https://ziggit.dev/u/rosew0od)\
**Post date:** [June 16, 2026, 7:13pm UTC](https://ziggit.dev/t/unexpected-leak/16208/2 "2026-06-16T19:13:48Z")

</div>

Defers should be written in order of initialization, and you should use `Io.Writer.Allocating`:

```zig
const std = @import("std");
const Io = std.Io;

pub fn main(init: std.process.Init) !void {
    const gpa = init.gpa;

    var client: std.http.Client = .{ .allocator = gpa, .io = init.io };
    defer client.deinit();

    var body: Io.Writer.Allocating = .init(gpa);
    defer body.deinit();

    var redirect_buffer: [4096]u8 = undefined;
    const response = try client.fetch(.{
        .location = .{
            .url = "https://jsonplaceholder.typicode.com/posts/1",
        },
        .method = .GET,
        .redirect_buffer = &redirect_buffer,
        .response_writer = &body.writer,
    });

    if (response.status == .ok) {
        std.debug.print("Stored Input:\n{s}\n", .{body.written()});
    } else {
        std.debug.print("HTTP Error Status: {}\n", .{response.status});
    }
}

```

---

<div class="post-metadata">

**Author:** ![Harshit](https://ziggit.dev/letter_avatar_proxy/v4/letter/h/c57346/32.png) [@Harshit](https://ziggit.dev/u/Harshit)\
**Post date:** [June 16, 2026, 7:33pm UTC](https://ziggit.dev/t/unexpected-leak/16208/3 "2026-06-16T19:33:06Z")

</div>

I copied your code  
and I did like this and we are getting the output

```zig
const std = @import("std");
const Io = std.Io;

pub fn main(init: std.process.Init) !void {
    const gpa = init.gpa;

    var client = std.http.Client{ .allocator = gpa, .io = init.io };
    defer client.deinit(); // <- Here

    var redirect_buffer: [4096]u8 = undefined;
    var allocating_writer = std.Io.Writer.Allocating.init(gpa);
    defer allocating_writer.deinit();

    const response = client.fetch(.{
        .location = .{
            .url = "https://jsonplaceholder.typicode.com/posts/1",
        },
        .method = .GET,
        .redirect_buffer = &redirect_buffer,
        .response_writer = &allocating_writer.writer,
    }) catch |err| {
        std.debug.print("Error fetch response: {any}", .{err});
        return;
    };

    if (response.status == .ok) {
        var data = allocating_writer.toArrayList();
        defer data.deinit(gpa);

        std.debug.print("Stored Input:\n{s}\n", .{data.items});
    } else {
        std.debug.print("HTTP Error Status: {}\n", .{response.status});
    }
}

```

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [June 17, 2026, 5:21am UTC](https://ziggit.dev/t/unexpected-leak/16208/4 "2026-06-17T05:21:56Z")

</div>

This is a common mistake; `Writer.fromArrayList` does **not** create a growable writer, rather it only writes to the unused capacity of the array lists buffer without growing.

The reason you got a leak is because it sets the array list to `empty`, it does not know about the allocated buffer anymore so it can’t free it on `deinit`.  
Instead, you would have to free `response_writer.buffer`.

What you likely want instead is `Writer.Allocating` as @rosew0od suggested.

* * *

when you get an adequate response you can mark it as the solution with the checkbox button on the bottom of the response.
