EpicGames/lore · error · anyhow::Error
Immutable store must be a local store
Error message
Immutable store must be a local store
What it means
GrpcInternalServer::with_components requires the provided immutable store to be a lore_storage::LocalImmutableStore-backed store; if local_immutable_store.is_local() is false it returns this error. The internal gRPC server (node-to-node APIs) only works against local disk storage.
Solutions
- Configure a LocalImmutableStore (local disk path) for the internal gRPC server.
- If using remote storage, disable the components that require the internal server or use a local cache/staging store alongside it.
- Audit the store construction call site to ensure the local store, not the generic one, is passed.
Example fix
// before
let store = Arc::new(S3ImmutableStore::new(...));
GrpcInternalServer::with_components(store, ...)
// after
let store = Arc::new(LocalImmutableStore::new("/data/lore"));
GrpcInternalServer::with_components(store, ...) Defensive patterns
Strategy: validation
Validate before calling
if !local_immutable_store.is_local() {
return Err("internal gRPC server requires a LocalImmutableStore");
} Try / catch
match GrpcInternalServer::with_components(...) {
Err(e) if e.to_string() == "Immutable store must be a local store" => {
// switch config to a local-disk store or disable internal server
}
other => other?,
} Prevention
- Pair the internal gRPC server strictly with LocalImmutableStore in deployment templates.
- Document that object-store backends cannot back node-to-node internal APIs.
- Assert storage backend type in an integration smoke test before rollout.
When it happens
Trigger: Calling GrpcInternalServer::with_components with a non-local immutable store (e.g. S3/remote object-store implementation) passed as local_immutable_store.
Common situations: Deployments configured with a remote/cloud storage backend but still launching the internal gRPC server; wiring the wrong Arc<dyn ImmutableStore> into with_components; config switched from local disk to object storage without disabling internal server features that require locality.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Maintenance TLS is partially configured: cert_file and…
- Missing gRPC settings
- Missing gRPC internal settings
- [environment.endpoint] auth_url is set but [server.auth] is…
- [environment.endpoint] auth_url and [server.auth]…
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/4aba4e3d5c2874c5.
Report an issue: GitHub.
Appendix: source
Thrown at lore-server/src/grpc/grpc_internal_server.rs:87
pub struct WantsComponents(());
impl GrpcInternalServerBuilder<WantsComponents> {
pub fn new() -> Self {
Self(WantsComponents(()))
}
pub fn with_components(
self,
local_immutable_store: Arc<dyn ImmutableStore>,
immutable_store: Arc<dyn ImmutableStore>,
mutable_store: Arc<dyn MutableStore>,
notification_sender: Arc<dyn NotificationSender>,
hook_dispatcher: Arc<HookDispatcher>,
environment: EnvironmentConfig,
) -> anyhow::Result<GrpcInternalServerBuilder<WantsTlsConfig>> {
if !local_immutable_store.is_local() {
return Err(anyhow!("Immutable store must be a local store"));
}
Ok(GrpcInternalServerBuilder(WantsTlsConfig {
local_immutable_store,
immutable_store,
mutable_store,
notification_sender,
hook_dispatcher,
environment,
}))
}
}
pub struct WantsTlsConfig {
local_immutable_store: Arc<dyn ImmutableStore>,
immutable_store: Arc<dyn ImmutableStore>,
mutable_store: Arc<dyn MutableStore>,
notification_sender: Arc<dyn NotificationSender>,View on GitHub (pinned to 074eb0b0d1)