EpicGames/lore · error

Missing Internal QUIC config

Error message

Missing Internal QUIC config

What it means

The internal QUIC server reads its configuration from `settings.server.quic_internal` and aborts startup with this error when the field is None. The internal QUIC endpoint (used for ImmutableLocal* opcodes and internal traffic) needs explicit bind/TLS/timeout settings, so its absence is fatal.

Solutions

  1. Add a `[server.quic_internal]` section to the settings file with the internal bind address and options.
  2. Disable/remove the internal QUIC endpoint from the server's endpoint configuration if it is not used.
  3. Note that the internal server does not fall back to `server.quic`; configure it explicitly.

Example fix

// before
[server.quic]
bind = "0.0.0.0:4433"  # only public configured
// after
[server.quic_internal]
bind = "127.0.0.1:4434"
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check internal QUIC config before enabling the internal endpoint
if settings.server.endpoints.contains(&"quic_internal".into())
    && settings.server.quic_internal.is_none()
{
    return Err(anyhow!("internal QUIC endpoint requires [server.quic_internal] settings"));
}

Prevention

When it happens

Trigger: Launching the internal QUIC endpoint in `async_main` while the settings lack a `server.quic_internal` section, hitting `ok_or(anyhow!("Missing Internal QUIC config"))`.

Common situations: New deployments that enable the internal endpoint but were set up from an older config that predated `quic_internal`; environments where only the public `server.quic` was configured; operators assuming the internal server inherits public QUIC settings.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/3075822c99c45fd7. Report an issue: GitHub.

Appendix: source

Thrown at lore-server/src/server.rs:2103

                 clients"
            );
        }
        // Without mTLS the certificate is only there to satisfy the TLS
        // handshake — peers connect over `quic://` and do not validate it — so
        // an ephemeral one keeps the endpoint zero-config. Under mTLS the
        // certificate is the authentication, and a generated one would be
        // worthless, so that path keeps demanding a configured triple.
        let generate_ephemeral_cert = security == EndpointSecurity::Untrusted;
        lore_spawn!(endpoints, {
            let immutable_store = immutable_store.clone();
            let settings = settings.clone();
            let shutdown_rx = _shutdown_rx.clone();
            let user_agent_filter = user_agent_filter.clone();

            let quic_settings = settings
                .server
                .quic_internal
                .ok_or(anyhow!("Missing Internal QUIC config"))?;
            let request_handler_timeout = quic_settings
                .handler_timeout_seconds
                .map(Duration::from_secs);

            let local_immutable_store = local_store().unwrap_or_else(|| {
                warn!("No local store available for internal QUIC server, ImmutableLocal* opcodes will route to the main store");
                immutable_store.clone()
            });

            let process_limit = quic_settings
                .stream_message_limit
                .unwrap_or(replication_store_service::DEFAULT_CLIENT_MESSAGE_LIMIT);
            let limits = AdmissionLimits {
                process_limit,
                inflight_limit: connection_inflight_limit(&quic_settings, process_limit),
                handler_timeout: request_handler_timeout,
                permit_timeout: quic_settings.permit_timeout_ms.map(Duration::from_millis),
            };

View on GitHub (pinned to 074eb0b0d1)