{"record":{"id":"e81b23b0e0a47cc4","repo":"EpicGames/lore","slug":"err","errorCode":null,"errorMessage":"{} {err}","messagePattern":"\\{\\} \\{err\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"lore-server/src/http/server.rs","lineNumber":225,"sourceCode":"        anyhow::bail!(\n            \"presigned_url_hmac_key must be at least {MIN_HMAC_KEY_BYTES} bytes, got {}\",\n            key_bytes.len()\n        );\n    }\n\n    let key_id = blake3::hash(&key_bytes).to_hex()[..16].to_string();\n    let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, &key_bytes);\n\n    Ok(Some(PresignConfig {\n        hmac_key,\n        key_id,\n        min_ttl_seconds: settings.min_ttl_seconds,\n        default_ttl_seconds: settings.default_ttl_seconds,\n        max_ttl_seconds: settings.max_ttl_seconds,\n        content_type_allowlist: ContentTypeAllowlist::try_from_policy(\n            &settings.content_type_policy,\n        )\n        .map_err(|err| anyhow!(\"{} {err}\", presign_content_type_field(err.field())))?,\n    }))\n}\n\nimpl LoreHttpServer {\n    /// Starts a minimal HTTP server that only serves the `/health_check` endpoint.\n    ///\n    /// Used during maintenance mode so that load balancers and monitoring systems\n    /// can still reach the server. Always returns 200 OK (store health checks are\n    /// disabled since the server is intentionally in a reduced state).\n    pub async fn serve_maintenance(\n        host: String,\n        port: i32,\n        user_agent_filter: Arc<UserAgentFilter>,\n        signal: impl Future<Output = ()> + Send + 'static,\n    ) -> Result<()> {\n        let addr = SocketAddr::from_str(format!(\"{host}:{port}\").as_str())\n            .map_err(|err| anyhow!(\"Failed to start maintenance HTTP server: {err}\"))?;\n        info!(\"Starting Lore maintenance HTTP Server: {}\", &addr);","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-server/src/http/server.rs#L207-L243","documentation":"build_presign_config converts the content-type policy into a ContentTypeAllowlist via try_from_policy; if the policy is invalid, the allowlist's own error is prefixed with the offending field name and propagated. The server cannot start with a presign content-type policy that references unknown or disallowed fields.","triggerScenarios":"PresignSettings.content_type_policy fails ContentTypeAllowlist::try_from_policy — e.g. a content type in an extra-allowed list that is never allowed, or a malformed policy field (the err.field() name appears in the message).","commonSituations":"Operators add custom content types to the presign allow/deny policy that violate the policy rules; typos in content-type strings; a policy edited after an upgrade tightened validation.","solutions":["Read the prefixed field name in the message to identify which policy entry is invalid.","Fix or remove the offending content type in settings.presign.content_type_policy.","Consult the builtin allowlist policy and model custom entries on its format.","Add a unit test mirroring build_presign_config_rejects_never_allowed_extra_type for your policy."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight: build the allowlist the same way the server does\nContentTypeAllowlist::try_from_policy(&settings.content_type_policy)\n    .map_err(|e| anyhow!(\"{} {e}\", presign_content_type_field(e.field())))?;","typeGuard":null,"tryCatchPattern":"// Startup validation in the deploy harness\nmatch ContentTypeAllowlist::try_from_policy(&policy) {\n    Ok(_) => {},\n    Err(e) => eprintln!(\"bad presign content_type_policy field '{}': {e}\", e.field()),\n}","preventionTips":["Mirror the builtin content-type policy and only append entries known to be allowed.","Add unit tests for every custom policy change (see build_presign_config_rejects_never_allowed_extra_type).","Validate config in CI with the same try_from_policy call."],"tags":["config","content-type","validation","startup"],"backgroundTag":"schema-validation-failed","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}