Skip to content

DNS resolution fails for URIs with a www subdomain #25811

@JoshLankford

Description

@JoshLankford

Zig Version

0.16.0-dev.1225+bf9082518

Steps to Reproduce and Observed Behavior

Issue
std.http.Client.fetch returns error.InvalidDnsCnameRecord for URIs with www subdomain or domains that redirect to www . This occurs in Arch Linux x86_64 and Ubuntu x86_64 but does not on macOS (15.6.1) aarch64. Most of the time removing www from the URI will bypass the issue however for domains with an auto redirect to www it requires a host override.

Example 1

const std = @import("std");

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    defer _ = gpa.deinit();
    const alloc = gpa.allocator();

    var io_threaded: std.Io.Threaded = .init(alloc);
    defer io_threaded.deinit();
    const io = io_threaded.io();

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

    var result_body = std.Io.Writer.Allocating.init(alloc);
    defer result_body.deinit();

    const response = try client.fetch(.{
        .location = .{ .url = "https://www.github.com/" },
        .response_writer = &result_body.writer,
    });

    if (response.status.class() == .success) {
        std.debug.print("{s}\n", .{result_body.written()});
    } else {
        std.debug.print("Request failed: {?s}\n", .{response.status.phrase()});
    }
}

Example 2 (redirect)

const std = @import("std");

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    defer _ = gpa.deinit();
    const alloc = gpa.allocator();

    var io_threaded: std.Io.Threaded = .init(alloc);
    defer io_threaded.deinit();
    const io = io_threaded.io();

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

    var result_body = std.Io.Writer.Allocating.init(alloc);
    defer result_body.deinit();

    const response = try client.fetch(.{
        .location = .{ .url = "https://cms.gov/" },
        .response_writer = &result_body.writer,
        // .headers = .{ .host = .{ .override = "www.cms.gov" } },
        // host override bypasses the issue
    });

    if (response.status.class() == .success) {
        std.debug.print("{s}\n", .{result_body.written()});
    } else {
        std.debug.print("Request failed: {?s}\n", .{response.status.phrase()});
    }
}

Error

zig run ./test_0.16.zig
error: InvalidDnsCnameRecord
/home/j/.local/share/mise/installs/zig/master/lib/std/Io/net/HostName.zig:246:13: 0x11e1ea1 in connect (std.zig)
            try end;
            ^
/home/j/.local/share/mise/installs/zig/master/lib/std/http/Client.zig:1447:18: 0x11c0644 in connectTcpOptions (std.zig)
    var stream = try host.connect(io, port, .{ .mode = .stream });
                 ^
/home/j/.local/share/mise/installs/zig/master/lib/std/http/Client.zig:1419:5: 0x11beb67 in connectTcp (std.zig)
    return connectTcpOptions(client, .{ .host = host, .port = port, .protocol = protocol });
    ^
/home/j/.local/share/mise/installs/zig/master/lib/std/http/Client.zig:1592:14: 0x11aa310 in connect (std.zig)
    } orelse return client.connectTcp(host, port, protocol);
             ^
/home/j/.local/share/mise/installs/zig/master/lib/std/http/Client.zig:1708:18: 0x11953bc in request (std.zig)
        break :c try client.connect(host_name, uriPort(uri, protocol), protocol);
                 ^
/home/j/.local/share/mise/installs/zig/master/lib/std/http/Client.zig:1791:15: 0x1182d72 in fetch (std.zig)
    var req = try request(client, method, uri, .{
              ^
/home/j/dev/example/test_0.16.zig:21:22: 0x1180c06 in main (test_0.16.zig)
    const response = try client.fetch(.{
                     ^

Additional Info
I cannot reproduce this in zig 0.15.2.

Expected Behavior

URIs with a www subdomain (or redirects) should resolve.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorstandard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions