EpicGames/lore · error · anyhow::Error

Missing gRPC internal settings

Error message

Missing gRPC internal settings

What it means

Thrown by launch_grpc_internal_server when settings.server.grpc_internal is None. The internal gRPC server needs its own host/port settings to bind; startup aborts instead of guessing a default address.

Solutions

  1. Add a [server.grpc_internal] section with host and port to the config file.
  2. Verify the internal server is enabled in the version being run and the section name matches the schema.
  3. Check that the correct config file is being loaded for this deployment mode.

Example fix

# before
[server]
# no grpc_internal section

# after
[server.grpc_internal]
host = "127.0.0.1"
port = 50052
Defensive patterns

Strategy: validation

Validate before calling

if settings.server.grpc_internal.is_none() {
    return Err(anyhow!("server.grpc_internal section missing from config"));
}

Type guard

fn grpc_internal_ready(settings: &Settings) -> bool {
    settings.server.grpc_internal.is_some()
}

Prevention

When it happens

Trigger: Calling launch_grpc_internal_server with a Settings whose settings.server.grpc_internal field is None (missing [server.grpc_internal] section in config).

Common situations: Config file predates the internal gRPC feature; section omitted from a minimal deployment config; key rename across versions leaves the field unset.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

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

             to explicitly accept the security exposure"
        )),
    }
}

#[allow(clippy::too_many_arguments)]
async fn launch_grpc_internal_server(
    settings: Settings,
    user_agent_filter: Arc<UserAgentFilter>,
    immutable_store: Arc<dyn ImmutableStore>,
    mutable_store: Arc<dyn MutableStore>,
    notification_sender: Arc<dyn NotificationSender>,
    hook_dispatcher: Arc<HookDispatcher>,
    mut shutdown_rx: tokio::sync::watch::Receiver<bool>,
) -> Result<()> {
    let grpc_settings = settings
        .server
        .grpc_internal
        .ok_or(anyhow!("Missing gRPC internal settings"))?;

    let addr =
        SocketAddr::from_str(format!("{}:{}", grpc_settings.host, grpc_settings.port).as_str())?;

    info!("Starting Lore gRPC internal server: {}", &addr);

    let (cert_path, key_path, cert_chain_path) =
        if let Some(cert_settings) = grpc_settings.certificate {
            (
                Some(cert_settings.cert_file),
                Some(cert_settings.pkey_file),
                cert_settings.cert_chain,
            )
        } else {
            (None, None, None)
        };

    let rpc_timeout = Duration::from_secs(grpc_settings.request_handler_timeout_seconds);

View on GitHub (pinned to 074eb0b0d1)