# Understanding the `--fixed-region` Flag in `tailcat genkey`

> Discover how the --fixed-region flag in tailcat genkey binds your server to a specific DERP region across restarts. Learn to embed region identifiers for consistent performance.

- Repository: [Tailscale/tailcat](https://github.com/tailscale/tailcat)
- Tags: how-to-guide
- Published: 2026-08-30

---

**The `--fixed-region` flag discovers the nearest DERP region once during key generation and embeds that region identifier directly into the generated token and key file, ensuring the server binds to the same region across restarts.**

The `tailcat` tool from the `tailscale/tailcat` repository enables secure TCP tunnels over Tailscale. When running `tailcat genkey`, the `--fixed-region` flag determines how the server selects its Designated Encrypted Relay Protocol (DERP) region—either pinning it permanently at generation time or deferring the choice until startup.

## How `--fixed-region` Works

When you invoke `tailcat genkey --fixed-region`, the tool performs a one-time DERP discovery probe to identify the geographically nearest relay region. According to the source code in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) at line 1000, this boolean flag triggers an immediate region selection that gets persisted in two places:

- The private key file stored at `~/.config/tailcat/keys/default.private.json`
- The connection token (beginning with `tc…`) printed to stdout

This baked-in region identifier ensures that subsequent server restarts use the exact same relay without re-probing the DERP map. The detailed rationale appears in [`README.md`](https://github.com/tailscale/tailcat/blob/main/README.md) lines 94-100, which explains that this behavior keeps DNS-published tokens valid for future clients even after the server process restarts.

## Default Behavior vs. Fixed Region Selection

Without the `--fixed-region` flag, `tailcat genkey` defaults to `--region=auto`. This stores a "pick at startup" directive in the key file rather than a specific region ID.

**Default (`--region=auto`):**

- Region selection occurs every time the server starts
- The server may bind to different DERP relays after restarts
- Tokens remain valid but endpoint consistency is not guaranteed

**Fixed (`--fixed-region`):**

- Region is selected once during key generation
- The same DERP region is used for the lifetime of the key
- Critical for stable DNS records and firewall rules

The flag parser in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) enforces mutual exclusion—you cannot use `--fixed-region` simultaneously with an explicit `--region=<name>` argument.

## Practical Usage Examples

### Generating a Fixed-Region Key

Use the following command to create a server key locked to the nearest DERP region:

```bash

# Generate a server key with region pinned at creation time

$ tailcat genkey --fixed-region

# → writes ~/.config/tailcat/keys/default.private.json

# → prints a token (tc…); the token already contains the chosen region ID

```

The generated token encodes the region identifier, meaning any client connecting with this token will route through the same DERP relay regardless of when the server last restarted.

### Programmatic Usage in Go

When using the Tailcat Go library directly, the `Server` struct handles region configuration through its initialization flow. While the library automatically picks the nearest region when starting with a zero-value configuration, keys generated with `--fixed-region` override this behavior by reading the embedded region from the token:

```go
package main

import (
    "fmt"
    "log"
    "net"

    "github.com/tailscale/tailcat"
)

func main() {
    s := &tailcat.Server{
        OnTCP: func(port uint16) func(net.Conn) {
            return func(c net.Conn) {
                fmt.Fprintf(c, "hello from port %v\n", port)
                c.Close()
            }
        },
    }
    if err := s.Start(); err != nil {
        log.Fatal(err)
    }
    fmt.Println(s.ConnBlob()) // token embeds the fixed DERP region
}

```

The [`tailcat.go`](https://github.com/tailscale/tailcat/blob/main/tailcat.go) file contains the core server implementation that consumes this baked-in region information from the connection token when `Start()` is called.

## Source Code Implementation

The `--fixed-region` flag is implemented across several files in the `tailscale/tailcat` repository:

- **[`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go)** (line 1000): Defines the boolean flag, its description, and enforces mutual exclusion with the `--region` argument
- **[`disco.go`](https://github.com/tailscale/tailcat/blob/main/disco.go)**: Handles the actual DERP discovery logic used during the one-time probe when `--fixed-region` is requested
- **[`pickregion.go`](https://github.com/tailscale/tailcat/blob/main/pickregion.go)**: Contains the fallback region selection logic used when the flag is not set (automatic selection mode)
- **[`README.md`](https://github.com/tailscale/tailcat/blob/main/README.md)** (lines 94-100): Documents the user-level behavior and explains that the nearest DERP region is discovered once and reused on subsequent restarts

When the flag is active, the region selection logic in [`disco.go`](https://github.com/tailscale/tailcat/blob/main/disco.go) runs during key generation rather than server startup, with the result persisted by the key storage handler in the main command file.

## Summary

- **`--fixed-region`** performs DERP discovery once at key-generation time and stores the region ID in both the key file and connection token
- **Default behavior** (`--region=auto`) defers region selection until server startup, potentially choosing different regions after restarts
- **Use case**: Essential for maintaining stable DNS records and ensuring tokens remain valid across server restarts
- **Implementation**: Defined in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) with discovery logic in [`disco.go`](https://github.com/tailscale/tailcat/blob/main/disco.go) and storage handled by the core server in [`tailcat.go`](https://github.com/tailscale/tailcat/blob/main/tailcat.go)
- **Mutual exclusion**: Cannot be combined with explicit `--region=<name>` arguments

## Frequently Asked Questions

### What is a DERP region in Tailscale?

A DERP (Designated Encrypted Relay Protocol) region is a relay server that helps establish connections when direct peer-to-peer links are impossible due to NAT or firewall constraints. Each region consists of multiple servers in a specific geographic location, and Tailscale clients automatically select the nearest low-latency region for optimal performance.

### Can I change the region after generating a key with `--fixed-region`?

No, the region is permanently embedded in the private key file and connection token. To use a different DERP region, you must generate a new key pair using `tailcat genkey --fixed-region` (which selects the new nearest region) or explicitly specify a region with `--region=<name>` without using the `--fixed-region` flag.

### Does `--fixed-region` conflict with the `--region` flag?

Yes, these options are mutually exclusive. The command-line parser in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) enforces that you cannot use `--fixed-region` alongside an explicit `--region=<name>` argument. You must choose between automatic discovery at generation time (`--fixed-region`), manual specification (`--region=<name>`), or automatic discovery at startup (default).

### Where is the fixed region identifier stored?

The region identifier is stored in two locations: first, in the private key JSON file at `~/.config/tailcat/keys/default.private.json` on the server; second, encoded within the connection token string (starting with `tc…`) that the command prints. The server reads this identifier from the key file on startup, while clients receive it through the token.