# How to Configure croc for a Local Network: Complete Setup Guide

> Learn how to configure croc for a local network with this setup guide. Disable automatic relays, host your own, and ensure matching ports for secure file transfers.

- Repository: [Zack/croc](https://github.com/schollz/croc)
- Tags: how-to-guide
- Published: 2026-07-27

---

**To run croc entirely on a local network, disable the automatic local relay with `--no-local`, point both peers to a LAN-hosted relay using `--relay <ip>`, and ensure matching `--ports` on all commands.**

When transferring files between machines on the same LAN, you can configure croc for a local network to bypass public infrastructure entirely. This setup keeps traffic internal to your network, eliminates external dependencies, and often improves transfer speeds. The `schollz/croc` repository supports this through specific CLI flags that disable NAT traversal and target a self-hosted relay.

## Why Use croc on a Local Network?

By default, croc attempts to traverse NAT using public relay servers, which routes your data through the internet even when both devices sit next to each other. For LAN-only transfers, this adds unnecessary latency and security exposure. Running croc on a local network ensures that file transfers never leave your internal infrastructure, making it ideal for air-gapped environments, sensitive data transfers, or high-speed exchanges between workstations.

## Core CLI Flags for Local Configuration

The command-line interface defines the flags that control relay behavior in [`src/cli/cli.go`](https://github.com/schollz/croc/blob/main/src/cli/cli.go).

### Disable Automatic Local Relay with `--no-local`

The `--no-local` flag prevents croc from spawning a temporary local relay used for NAT piercing. According to the source in [[`cli.go`](https://github.com/schollz/croc/blob/main/cli.go)](https://github.com/schollz/croc/blob/main/src/cli/cli.go#L76‑L81), this flag is essential for pure LAN operation where NAT traversal is unnecessary and can interfere with direct connections.

When sending files, include this flag to ensure croc connects only to your specified relay rather than attempting to negotiate a peer-to-peer connection through external means.

### Specify the Relay Host with `--relay`

Use the `--relay` flag to direct both sender and receiver to a fixed host on your LAN. In [[`cli.go`](https://github.com/schollz/croc/blob/main/cli.go)](https://github.com/schollz/croc/blob/main/src/cli/cli.go#L50‑L51), this flag is parsed and stored in the `croc.Options` struct (defined in [[`croc.go`](https://github.com/schollz/croc/blob/main/croc.go)](https://github.com/schollz/croc/blob/main/src/croc/croc.go#L150‑L166)).

Supply a local IP address or hostname without a URL scheme, such as `192.168.1.10` or `fileserver.local`.

### Define Allowed Ports with `--ports`

The `--ports` flag specifies which ports the relay will expose for WebSocket connections. As implemented in [[`cli.go`](https://github.com/schollz/croc/blob/main/cli.go)](https://github.com/schollz/croc/blob/main/src/cli/cli.go#L98‑L99), this takes a comma-separated list like `9009,9010,9011,9012`. Both the relay server and all clients must use identical port configurations.

### Bind the Relay Server with `--bind`

When starting the relay using `croc serve`, the `--bind` flag controls the listening interface. In [[`cli.go`](https://github.com/schollz/croc/blob/main/cli.go)](https://github.com/schollz/croc/blob/main/src/cli/cli.go#L11‑L12) (within the serve command definition), this defaults to localhost but should be set to `0.0.0.0:PORT` to accept connections from other LAN machines.

## How croc Processes Relay Addresses

Internally, croc normalizes the relay address through the `normalizeRelayAddress` function found in [[`croc.go`](https://github.com/schollz/croc/blob/main/croc.go)](https://github.com/schollz/croc/blob/main/src/croc/croc.go#L2147‑L2154). If the provided address lacks a scheme (e.g., `https://`), it treats the input as a plain host name, appending the default port. This logic ensures that simple LAN IPs like `192.168.1.10` resolve correctly to `192.168.1.10:9009` for the underlying TCP connection.

## Validation and Error Handling

The system validates relay configuration in [[`webrelay.go`](https://github.com/schollz/croc/blob/main/webrelay.go)](https://github.com/schollz/croc/blob/main/src/webrelay/webrelay.go#L58‑L61). If you accidentally include a URL scheme (e.g., `http://192.168.1.10`), croc returns the error `relay must be a host, not a URL`. Always provide bare IP addresses or hostnames to avoid this validation failure.

## Step-by-Step Local Network Setup

Follow this workflow to transfer files exclusively over your LAN.

### 1. Start the Built-in Relay Server

Designate one machine as the relay host (e.g., `192.168.1.10`). Run:

```bash
croc serve --bind 0.0.0.0:9014 \
           --relay 192.168.1.10 \
           --ports 9009,9010,9011,9012

```

The `--bind 0.0.0.0:9014` instructs the embedded HTTP/WebSocket server to listen on all network interfaces, while `--relay` sets the advertised address that peers will use.

### 2. Send Files from the Source Machine

On the device hosting the files, disable the automatic local relay and point to your LAN server:

```bash
croc send --relay 192.168.1.10 \
          --no-local \
          --ports 9009,9010,9011,9012 \
          myfile.txt

```

The `--no-local` flag prevents the sender from starting a temporary local relay, forcing it to connect directly to `192.168.1.10`.

### 3. Receive Files on the Destination Machine

On the receiving device, connect to the same relay:

```bash
croc receive --relay 192.168.1.10 \
             --ports 9009,9010,9011,9012

```

Because both peers contact the same LAN relay, the transfer occurs entirely over the local network without internet traversal.

## Summary

- **Use `--no-local`** (defined in [`cli.go`](https://github.com/schollz/croc/blob/main/cli.go) line 76) on the sender to disable automatic NAT traversal relays.
- **Set `--relay <host>`** to a LAN IP or hostname (parsed in [`cli.go`](https://github.com/schollz/croc/blob/main/cli.go) lines 50-51 and stored in `croc.Options` lines 150-166).
- **Match `--ports`** across all commands to ensure consistent WebSocket connectivity (configured in [`cli.go`](https://github.com/schollz/croc/blob/main/cli.go) lines 98-99).
- **Start the relay** with `croc serve --bind 0.0.0.0:PORT` to accept LAN connections.
- **Validate** that relay addresses contain no URL scheme to avoid errors from [`webrelay.go`](https://github.com/schollz/croc/blob/main/webrelay.go) lines 58-61.

## Frequently Asked Questions

### Do both the sender and receiver need the `--no-local` flag?

Only the sender requires `--no-local` to prevent spawning an unnecessary local relay for NAT traversal. However, both peers must specify identical `--relay` and `--ports` values to ensure they connect to the same LAN relay instance, as the configuration must match across the `croc.Options` struct used by both parties.

### Can I use a hostname instead of an IP address for the relay?

Yes. The `normalizeRelayAddress` function in [`croc.go`](https://github.com/schollz/croc/blob/main/croc.go) (lines 2147-2154) treats any string without a URL scheme as a valid host. You can use `fileserver.local` or similar hostnames, provided your LAN's DNS or hosts file resolves the name correctly. Just ensure you do not include `http://` or `https://`, or [`webrelay.go`](https://github.com/schollz/croc/blob/main/webrelay.go) will reject it with a validation error.

### Why does croc require a relay for local network transfers?

Croc uses a client-server architecture where both sender and receiver connect to a central relay that coordinates the WebSocket-to-TCP bridge, even on LANs. This design maintains croc's security model (end-to-end encrypted) and simplifies firewall traversal. By hosting the relay locally with `croc serve`, you keep this coordination internal while avoiding external infrastructure.

### What happens if I forget the `--no-local` flag?

Without `--no-local`, the sending instance attempts to establish a temporary local relay for NAT piercing, which can cause connection failures or suboptimal routing in LAN-only environments. According to [`cli.go`](https://github.com/schollz/croc/blob/main/cli.go) lines 76-81, this flag explicitly disables the automatic local relay logic, ensuring the client connects directly to your specified `--relay` host instead.