Minimal configuration
This page shows the smallest config file that can start the dataplane, accept DNS queries, and forward them to an upstream resolver. Use it when standing up a lab or following Install and run.
The control plane (gRPC and conduitctl) is opt-in: it is not started unless you add an explicit control: block. The minimal example below does not enable it.
Minimal means the fewest blocks you must author. Conduit fills in safe defaults for everything else at load time. This page covers only the three required blocks; field-level reference and tuning are described in Reference: config schema and the linked topic pages below.
Minimal example
Save the file below (for example as conduit.yaml). Lab examples use 127.0.0.1:15353 for Conduit’s DNS listener (avoiding UDP 5353, which is often mDNS on Linux). The pool points at 127.0.0.1:5300 — something must be listening there (for example a mock resolver or dnsmasq forwarding to a public resolver) before queries succeed.
schema_version: 1
listeners:
listeners:
- address: "127.0.0.1:15353"
protocol: udp
pools:
- name: default
backends:
- address: "127.0.0.1:5300"
That is a complete, runnable configuration. You do not need to declare forward, orchestrator, events, rhai, or control unless you want to change their defaults.
What each block does
schema_version
Required top-level key. The only accepted value is 1. Omitting the key fails YAML parsing; any other value fails validation.
listeners
Dataplane ingress: where clients send DNS queries. You need at least one entry under listeners.listeners with an address (ip:port) and protocol (udp or tcp).
When you omit listeners.threads and listeners.reuse_port, Conduit uses 1 thread and reuse_port: false. For every listener field, default, and validation rule, see Reference: listeners.
pools
Where Conduit forwards queries. Each pool has a unique name and at least one backend (address: "ip:port"). The name default is a convention for the catch-all pool when nothing else selects one.
Omitted weight on a backend defaults to 100 for load balancing. For selection behavior, multiple pools, and retries, see Pools and backends. For every pool and backend field, see Reference: pools.
Defaults you do not need to write yet
Conduit still loads and applies these blocks when they are absent from your file. You can add them later when you need to tune behavior.
| Block | What Conduit applies when omitted | Learn more |
|---|---|---|
forward | Upstream timeout 2000 ms, 100 outstanding queries per backend, UDP-only transport | Reference: forward, Dual-stack forwarding |
orchestrator | 3 max attempts, 5000 ms max transaction duration, 1024 transaction table capacity | Reference: orchestrator, Retries and transactions |
control | Off when omitted — no gRPC listener; add a control: block with listen_address to enable conduitctl | gRPC and conduitctl, Reference: control |
events | Queue depth 4096, drop_oldest policy, no sinks | Event export, Reference: events |
rhai | Sandbox limits (10000 operations, call depth 32); no scripts unless you add them | Rhai, Sandbox limits |
To see the effective configuration after defaults are applied, run conduitctl validate --file conduit.yaml (offline validation and snapshot compile — no running server required), or follow Validate and run. To export normalized YAML from a running server with the control plane enabled, use conduitctl export — see Configuration model and Reload and export.
Optional blocks not in this example
You can add these once the baseline works — none are required to start Conduit:
- Rules — policy routing before forward
- Backend health — optional per-pool probes and passive fast-trip (
pools[].health; disabled by default) - Metrics and tracing — observability
- Event export (dnstap sinks) — requires
events.sinks - API keys and mTLS — control-plane security (requires an explicit
control:block)
To enable the control plane, add for example:
control:
listen_address: "127.0.0.1:5199"
Changing or adding control: via reload requires a process restart today; see Reload and export.
For the full query path (listen → policy → Lookup → send), see Architecture and packet path.
Validate and run
- Validate the file locally (no running server required):
conduitctl validate --file conduit.yaml
On success the command prints ok. Parse and validation errors are printed to stderr.
- Start Conduit with the config path as the first argument (see Install and run for build prerequisites):
target/release/conduit conduit.yaml
- Send a test query once an upstream is listening on the pool address (see First query):
dig @127.0.0.1 -p 15353 +time=3 +tries=1 example.com A
For file format, load behavior, and reload via the control plane, see Config file.
Related topics
- Install and run — build, start Conduit, prerequisites
- First query — send a test query through the minimal setup
- Config file — file format, validation, and load behavior
- Pools and backends — pool selection and backend weights
- Reference: config schema — field reference for every block