EpicGames/lore · error · anyhow::Error
Address was not set
Error message
Address was not set
What it means
The builder needs a listen address: either a caller-bound UdpSocket (whose local_addr is used) or an explicit address field. If neither is set, build() cannot produce a QuinnConfig and returns this error.
Solutions
- Call .address(addr) with the listen SocketAddr before build()
- Or bind a UdpSocket and pass it via the socket setter so local_addr can be used
- Ensure the config file's listen address is parsed and forwarded to the builder
Example fix
// before
let cfg = QuinnConfigBuilder::new().stream_handler_factory(f).build()?;
// after
let cfg = QuinnConfigBuilder::new().stream_handler_factory(f).address("0.0.0.0:443".parse()?).build()?; Defensive patterns
Strategy: validation
Validate before calling
if socket.is_none() && address.is_none() {
return Err("QUIC listen address must be provided (socket or address)".into());
} Try / catch
match cfg.build() {
Err(e) if e.to_string().contains("Address was not set") => eprintln!("set .address(...) or bind a socket before build"),
r => r?,
} Prevention
- Pass the listen address from parsed config into the builder explicitly
- Test server launch with the real production config in CI
When it happens
Trigger: Calling QuinnConfigBuilder::build() with no socket bound and no address set via the builder; both self.socket and self.address are None.
Common situations: Forgetting the .address(...) builder call after a refactor; config missing the listen address and no pre-bound socket supplied (e.g. socket-activation paths).
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/d5f21920dae7779d.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/quic/quinn/config.rs:202
self.transport_rtt = Some(rtt);
self
}
pub fn build(self) -> anyhow::Result<QuinnConfig> {
let stream_handler_factory = self
.stream_handler_factory
.ok_or(anyhow!("Stream handler factory was not set"))?;
let alpns = stream_handler_factory.supported_protocols();
if alpns.is_empty() {
return Err(anyhow!("No alpns provided"));
};
// A caller-bound socket is the truth about where this serves; asking it beats trusting an
// `address` set alongside it, which could disagree.
let address = match &self.socket {
Some(socket) => socket.local_addr()?,
None => self.address.ok_or(anyhow!("Address was not set"))?,
};
Ok(QuinnConfig {
server_metrics_name: self.server_metrics_name,
address,
socket: self.socket,
alpns,
cert_file: self.cert_file,
pkey_file: self.pkey_file,
cert_chain: self.cert_chain,
client_cert_verifier: self
.client_cert_verifier
.unwrap_or(Arc::new(NoClientAuth {})),
stream_handler_factory,
idle_timeout: self
.idle_timeout
.unwrap_or(Duration::from_millis(DEFAULT_IDLE_TIMEOUT_MILLIS)),
keep_alive: selfView on GitHub (pinned to 074eb0b0d1)