denoland/deno · error · TypeError

Unsupported transport

Error message

Unsupported transport: '${transport}'

What it means

Deno.listen() dispatches on args.transport (defaulting to "tcp") and recognizes exactly tcp, unix, vsock and tunnel in this build; every other value reaches the default case and throws TypeError(`Unsupported transport: '<transport>'`). Notably udp is NOT a listen() transport here — datagram sockets use Deno.listenDatagram — and there is no "tls" listener transport; TLS is per-connection (Deno.connectTls / Deno.startTls).

Solutions

  1. For TCP, omit transport or pass "tcp".
  2. For UDP, use Deno.listenDatagram({ transport: "udp", port }) or { transport: "unixpacket", path }.
  3. For TLS servers, listen on tcp and terminate TLS per connection (Deno.startTls / connectTls on the client side) — there is no listen({transport:"tls"}).
  4. Check your Deno version's docs for vsock and tunnel availability before using them.

Example fix

// before
const sock = Deno.listen({ transport: "udp", port: 53 }); // Unsupported transport: 'udp'

// after
const sock = Deno.listenDatagram({ transport: "udp", port: 53 });
Defensive patterns

Strategy: validation

Validate before calling

const LISTEN_TRANSPORTS = new Set(["tcp", "unix", "vsock", "tunnel"]);
function openListener(args: { transport?: string; [k: string]: unknown }) {
  const t = args.transport ?? "tcp";
  if (!LISTEN_TRANSPORTS.has(t)) {
    throw new TypeError(
      `unsupported listen transport '${t}'; use Deno.listenDatagram for udp, tcp has no 'tls' transport`,
    );
  }
  return Deno.listen(args as Parameters<typeof Deno.listen>[0]);
}

Type guard

const isListenTransport = (t: unknown): t is "tcp" | "unix" | "vsock" | "tunnel" =>
  t === "tcp" || t === "unix" || t === "vsock" || t === "tunnel";

Prevention

When it happens

Trigger: `Deno.listen({ transport: "udp", port: 53 })`; `Deno.listen({ transport: "tls", port: 443 })`; casing or typo errors like "TCP"/"ip"; a transport string sourced from config or cross-runtime code written against Node's vocabulary (dgram, tls).

Common situations: Assuming listen({transport:"udp"}) from older documentation — UDP moved to Deno.listenDatagram; expecting a TLS listener API similar to Node's tls.createServer; polyfills or shared code paths that pass Node transport names; vsock/tunnel unavailable on older Deno versions.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/92436722caf80723. Report an issue: GitHub.

Appendix: source

Thrown at ext/net/01_net.js:633

    }
    case "vsock": {
      const { 0: rid, 1: cid, 2: port } = op_net_listen_vsock(
        args.cid,
        args.port,
      );
      const addr = {
        transport: "vsock",
        cid,
        port,
      };
      return new Listener(rid, addr, "vsock");
    }
    case "tunnel": {
      const { 0: rid, 1: addr } = op_net_listen_tunnel();
      return new Listener(rid, addr, "tunnel");
    }
    default:
      throw new TypeError(`Unsupported transport: '${transport}'`);
  }
}

function validatePort(maybePort, isServer = false) {
  // A missing port means "any available port" (port 0) for servers. Clients
  // must always specify a port to connect to, so a missing port is left as-is
  // and rejected below.
  if (isServer && (maybePort === null || maybePort === undefined)) {
    maybePort = 0;
  }
  if (typeof maybePort !== "number" && typeof maybePort !== "string") {
    throw new TypeError(`Invalid port (expected number): ${maybePort}`);
  }
  if (maybePort === "") throw new TypeError("Invalid port: ''");
  const port = Number(maybePort);
  if (!NumberIsInteger(port)) {
    if (NumberIsNaN(port) && !NumberIsNaN(maybePort)) {
      throw new TypeError(`Invalid port: '${maybePort}'`);

View on GitHub (pinned to 9ad36f7a2c)