How to Debug Keylog Issues in iroh Connections

Enable TLS key logging in iroh by setting the SSLKEYLOGFILE environment variable and calling .keylog(true) on the EndpointBuilder, which writes pre-master secrets to the specified file via rustls.

The iroh networking library uses rustls for TLS encryption, providing a built-in mechanism to log cryptographic keys for debugging QUIC connections. When you need to inspect encrypted traffic with tools like Wireshark, enabling the keylog feature is essential. This guide explains how to debug keylog issues in iroh connections by examining the source code in the n0-computer/iroh repository.

How Key Logging Works in iroh

Iroh implements key logging through a coordinated chain between the endpoint builder and the TLS configuration layer. Understanding this flow helps diagnose why keys might not appear in your log file.

Endpoint Configuration

The keylog behavior is controlled by the EndpointBuilder in iroh/src/endpoint.rs. At lines 730–734, the builder maintains a keylog: bool field that defaults to false. You must explicitly enable it using the .keylog(true) method before constructing the endpoint.

let endpoint = Endpoint::builder()
    .keylog(true)  // Enables TLS key logging
    .bind(([0, 0, 0, 0], 0))?;

When the endpoint builds the QUIC client or server configuration, it passes this boolean flag to the TLS configuration helpers.

TLS Configuration

The actual key logging implementation resides in iroh/src/tls.rs at lines 74–107. The functions make_server_config and make_client_config accept the keylog argument. When set to true, they configure rustls to emit key material:

if keylog {
    cfg.key_log = Arc::new(rustls::KeyLogFile::new());
}

This delegates to rustls's KeyLogFile, which checks the SSLKEYLOGFILE environment variable and writes the TLS pre-master secret in the standard NSS key log format.

Common Symptoms and Root Causes

When debugging keylog issues in iroh connections, identify your specific symptom to isolate the root cause:

  • No keylog file created: The SSLKEYLOGFILE environment variable is unset or points to a non-writable directory. Verify with echo $SSLKEYLOGFILE and check filesystem permissions.
  • Empty keylog file: The keylog flag was not passed to the endpoint builder. Search your code for .keylog(true) and ensure it appears before .bind().
  • Stale or missing entries: The connection reused a cached session ticket before keylog was enabled. Clear the client's session cache or restart the endpoint to force a full handshake.
  • Application crashes: The rustls crate was compiled without the dangerous_configuration feature, which is required for key logging. Check your Cargo.toml for features = ["dangerous_configuration"].

Step-by-Step Debugging Procedure

Follow these steps to verify and fix key logging functionality:

  1. Set the environment variable

    Ensure SSLKEYLOGFILE is exported before your process starts:

    export SSLKEYLOGFILE=$HOME/iroh_keylog.txt
    touch $SSLKEYLOGFILE
  2. Enable keylog in your code

    Confirm the builder calls .keylog(true) as shown in iroh/examples/0rtt.rs at line 68:

    let endpoint = Endpoint::builder()
        .keylog(true)
        .bind(([0, 0, 0, 0], 0))?;
  3. Verify the TLS configuration

    Inspect iroh/src/tls.rs to confirm make_server_config or make_client_config contains the key logging logic:

    if keylog {
        cfg.key_log = Arc::new(rustls::KeyLogFile::new());
    }
  4. Validate the rustls version

    Check your Cargo.lock to ensure you are using a rustls version that supports KeyLogFile. If necessary, update your Cargo.toml:

    [dependencies]
    rustls = { version = "0.22", features = ["dangerous_configuration"] }
  5. Inspect the output

    After running a connection, verify the file contains entries starting with CLIENT_RANDOM or SERVER_HANDSHAKE:

    head -n 5 $SSLKEYLOGFILE

Working Code Example

Below is a complete example combining environment setup and endpoint configuration:

use iroh::endpoint::Endpoint;

fn main() -> anyhow::Result<()> {
    // Set before any connections are established
    std::env::set_var("SSLKEYLOGFILE", "/tmp/iroh_keys.log");
    
    let endpoint = Endpoint::builder()
        .keylog(true)  // Critical: enables key logging
        .bind(([0, 0, 0, 0], 0))?;
    
    // Proceed with connection logic...
    Ok(())
}

Key Source Files Reference

When debugging keylog issues in iroh connections, examine these specific files in the repository:

  • iroh/src/endpoint.rs: Contains the keylog field and builder method (lines 730–734).
  • iroh/src/tls.rs: Implements make_server_config and make_client_config; enables rustls key logging when the flag is true (lines 74–107).
  • iroh/examples/0rtt.rs: Reference implementation showing .keylog(true) usage (line 68).
  • Cargo.toml: Declares the rustls dependency; must include the dangerous_configuration feature.

Summary

  • Set the SSLKEYLOGFILE environment variable to a writable path before starting your application.
  • Enable the .keylog(true) method on the EndpointBuilder to pass the flag through to the TLS layer.
  • Verify the rustls dependency includes the dangerous_configuration feature in your Cargo.toml.
  • Check iroh/src/tls.rs to confirm KeyLogFile is instantiated when the flag is enabled.
  • Clear session caches if keys appear stale, as resumed connections may predate the keylog setting.

Frequently Asked Questions

Why is my keylog file empty even though SSLKEYLOGFILE is set?

The file remains empty when the .keylog(true) method is omitted from the EndpointBuilder or when the connection reuses a cached session ticket without performing a full handshake. Verify that your code explicitly calls .keylog(true) and restart the endpoint to ensure a fresh handshake occurs.

Does enabling key logging require special rustls features?

Yes, key logging requires the dangerous_configuration feature to be enabled in your Cargo.toml for the rustls crate. Without this feature flag, the KeyLogFile API is unavailable and the application may fail to compile or panic at runtime when key logging is attempted.

Is it safe to enable keylog in production applications?

No, enabling key logging exposes the pre-master secrets and compromises the confidentiality of all encrypted connections. According to the iroh source code, this feature is intended for debugging only, as demonstrated in example files like iroh/examples/0rtt.rs. Never enable .keylog(true) in production environments.

How can I verify the keylog is capturing the correct connection?

Inspect the keylog file for entries beginning with CLIENT_RANDOM or SERVER_HANDSHAKE. Each line corresponds to a specific TLS handshake. If you see entries but cannot decrypt traffic in Wireshark, ensure you are capturing the entire QUIC handshake from the initial Client Hello packet, as keys are only logged during the handshake phase.

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 →