How to Disable Relays in iroh Using the N0DisableRelay Preset

Use the N0DisableRelay preset when constructing your endpoint to set RelayMode::Disabled, ensuring the endpoint never discovers or contacts relay servers and relies exclusively on direct peer-to-peer paths.

Disabling relay functionality is critical when operating iroh in trusted LAN environments, air-gapped networks, or strict security contexts where external relay contact is prohibited. The N0DisableRelay preset provides an idiomatic, reusable configuration bundle that extends the standard N0 preset while forcing the relay mode to disabled. According to the iroh source code, this preset applies the base configuration and then explicitly invokes builder.relay_mode(RelayMode::Disabled) to block all relay-related traffic.

How the N0DisableRelay Preset Works

The preset system in iroh is built around the Preset trait defined in iroh/src/endpoint/presets.rs. This trait defines a single method:

fn apply(self, builder: Builder) -> Builder

The N0DisableRelay struct implements this trait by first delegating to the standard N0 preset (which configures DNS resolution, cryptographic providers, and other defaults) and then chaining a call to set the relay mode. Specifically, the implementation invokes builder.relay_mode(RelayMode::Disabled), ensuring that the resulting endpoint will skip relay discovery and operate in a relay-free mode.

Key implementation details from iroh/src/endpoint/presets.rs:

  • N0DisableRelay wraps the standard N0 configuration
  • The apply method returns a builder configured with RelayMode::Disabled
  • All connections must succeed via direct paths such as local network or hole-punching

Creating a Relay-Free Endpoint

To create an endpoint that never contacts relay servers, pass N0DisableRelay to the endpoint builder:

use iroh::{Endpoint, endpoint::presets};

let endpoint = Endpoint::builder(presets::N0DisableRelay)
    .bind()
    .await
    .expect("failed to bind endpoint");

This configuration ensures that endpoint.relay_mode() returns RelayMode::Disabled, and the node will not attempt to discover or use any relay servers defined in the default N0 configuration.

Alternative Configuration Approaches

Manual Relay Mode Configuration

You can achieve the same effect without the preset by manually configuring the standard N0 preset and explicitly disabling relays:

use iroh::{Endpoint, RelayMode, endpoint::presets};

let ep = Endpoint::builder(presets::N0)
    .relay_mode(RelayMode::Disabled)
    .bind()
    .await
    .unwrap();

This approach provides identical behavior to N0DisableRelay but allows for additional builder customization before binding.

Comparison with Default N0 Behavior

The default N0 preset enables relay functionality for NAT traversal, while N0DisableRelay explicitly removes it:

// Uses default relay servers
let ep_with_relay = Endpoint::builder(presets::N0)
    .bind()
    .await
    .unwrap();

// Never contacts relay servers
let ep_without_relay = Endpoint::builder(presets::N0DisableRelay)
    .bind()
    .await
    .unwrap();

Verifying the Relay Configuration

After binding, verify that relays are disabled by checking the endpoint's relay mode:

assert_eq!(endpoint.relay_mode(), RelayMode::Disabled);

This assertion confirms that the endpoint configuration in iroh/src/endpoint/builder.rs correctly applied the disabled state and that no relay connections will be attempted during peer connection establishment.

Summary

  • The N0DisableRelay preset in iroh/src/endpoint/presets.rs provides the canonical way to disable relay functionality.
  • It implements the Preset trait by applying N0 defaults and then setting RelayMode::Disabled.
  • Use Endpoint::builder(presets::N0DisableRelay) for relay-free operation in LAN or restricted environments.
  • Manual configuration via .relay_mode(RelayMode::Disabled) offers equivalent behavior for custom setups.
  • Verify the configuration at runtime using endpoint.relay_mode().

Frequently Asked Questions

What is the difference between N0DisableRelay and manually setting RelayMode::Disabled?

There is no functional difference. The N0DisableRelay preset is a convenience wrapper that applies the standard N0 configuration and then calls .relay_mode(RelayMode::Disabled). Both approaches result in an endpoint that never contacts relay servers, but the preset provides a cleaner, reusable configuration pattern.

When should I disable relays in an iroh application?

Disable relays when operating in fully trusted local networks, air-gapped environments, or when enforcing strict security policies that prohibit external relay contact. Without relays, iroh relies entirely on direct peer-to-peer connections, which requires either public IP addresses or successful hole-punching through NAT devices.

Does disabling relays prevent the endpoint from accepting incoming connections?

No, disabling relays does not block incoming connections. It only prevents the endpoint from using relay servers as intermediaries for NAT traversal. The endpoint can still accept direct connections from peers on the same local network or from peers that can establish direct UDP paths via hole-punching.

Where is the RelayMode enum defined in the iroh codebase?

The RelayMode enum is typically defined in iroh/src/relay_mode.rs or within the endpoint module. The Disabled variant is used by iroh/src/endpoint/builder.rs to configure the builder and by iroh/src/endpoint/presets.rs to implement the N0DisableRelay preset.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →