# How to Validate a TOML Deployment Configuration Before Starting the Switchyard Server

> Validate your TOML deployment configuration before starting the Switchyard server with the --dry-run flag. Detect and fix errors for clients targets and routes before deployment.

- Repository: [NVIDIA-NeMo/Switchyard](https://github.com/NVIDIA-NeMo/Switchyard)
- Tags: how-to-guide
- Published: 2026-08-17

---

**Switchyard provides a `--dry-run` flag that parses and validates your TOML deployment file without binding network sockets, returning detailed errors if required fields like `clients`, `targets`, or `routes` are misconfigured.**

The NVIDIA-NeMo/Switchyard inference router relies on TOML files to define LLM clients, routing targets, and traffic rules. Catching syntax errors or missing required fields before the server attempts to listen on a port prevents runtime crashes and deployment delays. The validation pipeline checks both TOML syntax and semantic correctness using the server's own configuration parser.

## How Validation Works Under the Hood

When you trigger a validation check, the server invokes the `server_state_from_toml` function located in [`crates/switchyard-server/src/config.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-server/src/config.rs). This function performs a three-stage check:

1. **Syntax parsing** – Uses `toml::from_str` to deserialize the file into the `ServerConfig` struct.
2. **Semantic validation** – Calls `config.validate()` to run custom logic (e.g., `validate_value`) ensuring every client has a valid `format`, every target has a `provider`, and route IDs are unique.
3. **State construction** – Attempts to build a `ServerState` without opening sockets.

If any stage fails, the function returns a `ServerResult` containing a descriptive `ServerError`, and the server exits before binding to any address.

```rust
// Located in crates/switchyard-server/src/config.rs (lines 46-54)
fn server_state_from_toml(toml: &str) -> ServerResult<ServerState> {
    let config: ServerConfig = toml::from_str(toml)
        .map_err(|error| ServerError::new(format!("Failed to parse TOML: {error}")))?;
    config.validate()?;               // runs the custom validation logic
    ServerState::new(config)          // builds the runnable state
}

```

## Validating via the Command Line

The `switchyard-server` binary exposes a `--dry-run` flag documented in [`docs/cli_reference.md`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/docs/cli_reference.md). This flag executes the validation pipeline described above without entering the async runtime or binding TCP sockets.

```bash

# Validate a deployment located at routes.toml

switchyard-server --config routes.toml --dry-run

```

- **Exit code 0** indicates the TOML is syntactically valid and all required fields are present.
- **Non-zero exit** prints a detailed error message pointing to the specific line or missing key (e.g., missing `api_key_env` in a `[clients]` block).

All `switchyard launch` commands internally run this same validation step before spawning Python-side launchers. If validation fails, the launch aborts immediately with the same diagnostic output.

## TOML Schema Requirements

The validation logic enforces the schema defined in [`docs/reference/toml_schema.md`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/docs/reference/toml_schema.md). A valid deployment file must contain three primary sections:

- **`[clients]`** – Defines LLM client interfaces. Each entry must specify `format` and `target`. Optional fields include `api_key_env`.
- **`[targets]`** – Defines backend endpoints. Each target requires a `provider` (e.g., `openai`, `nim`), a `url`, and credential handling instructions.
- **`[routes]`** – Maps clients to targets. Routes must have unique IDs and may include algorithm-specific configuration like `round_robin` or `weighted` parameters.

The `validate()` method iterates over these collections to ensure no route references a non-existent target and no client lacks a required format string.

## Programmatic Validation in Rust

You can reuse the server's validation logic in your own Rust tooling by importing the `config` module and calling `server_state_from_toml` directly.

```rust
use switchyard_server::config::{server_state_from_toml, ServerResult};

fn validate_toml(path: &str) -> ServerResult<()> {
    let toml = std::fs::read_to_string(path)
        .map_err(|e| format!("cannot read {path}: {e}"))?;
    server_state_from_toml(&toml).map(|_| ())
}

```

This pattern is useful for building custom deployment tools or pre-commit hooks that verify configuration files before they reach production servers.

## CI/CD Integration

Add the dry-run step to your continuous integration pipeline to catch configuration regressions before deployment.

```bash

# Example: Quick validation in a CI script

if ! switchyard-server --config my_deployment.toml --dry-run; then
    echo "❌ Deployment file is invalid – aborting build"
    exit 1
fi
echo "✅ Deployment file passes validation"

```

## Summary

- The `server_state_from_toml` function in [`crates/switchyard-server/src/config.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-server/src/config.rs) handles parsing and validation.
- Use `switchyard-server --config <file> --dry-run` to validate without starting the server.
- Validation checks TOML syntax, required fields in `[clients]`, `[targets]`, and `[routes]`, and internal consistency (e.g., route-to-target references).
- Exit code 0 confirms validity; any other code indicates the specific line and nature of the error.
- All `switchyard launch` commands perform this validation automatically.

## Frequently Asked Questions

### What exactly does the `--dry-run` flag check?

The `--dry-run` flag performs a full validation pass: it parses the TOML into a `ServerConfig`, runs the `validate()` method to check for required fields like `format` and `provider`, and attempts to construct a `ServerState`. It stops short of binding to any network socket or initializing the async runtime.

### Can I validate a TOML file without installing the full server?

No, the validation logic is compiled into the `switchyard-server` binary. However, you can run the validation on any machine (including CI runners) by installing the binary and running the `--dry-run` command. There is no separate lightweight validator utility.

### What happens if a route references a target that does not exist?

The `config.validate()` call will return a `ServerError`, and the validation will fail with a message indicating the orphaned route ID. The server will not start until every route points to a defined target in the `[targets]` section.

### Does validation check if the upstream LLM endpoints are reachable?

No. The dry-run validation only checks the local TOML configuration for syntactic and semantic correctness. It does not perform network health checks against the URLs defined in `[targets]`. Live endpoint verification occurs only after the server starts and attempts to route traffic.