How to get UGS to pull binaries from Horde

Hi,

I’m trying to figure out how to get UGS to pull precompiled binaries from Horde using artifacts.

Previously it was setup to pull P4 binary zips and worked. I recently got Horde to start publishing PCBs as artifacts, which seems to work fine but UGS doesn’t appear to pull any of them.

This is what my artefact looks like:

`{

“id”: “67eabaf9a5469ad837f2e9a3”,

“name”: “editor-win64-development”,

“type”: “ugs-pcb”,

“description”: “Editor Win64”,

“streamId”: “depot-stream”,

“change”: 88849,

“commitId”: {

“name”: “88849”,

“order”: 88849

},

“keys”: [

“job:67eab7d9a5469ad837f29d18”,

“job:67eab7d9a5469ad837f29d18/step:0dfe”,

“ugs-project=//depot/stream/projectname/projectname.uproject”

],

“metadata”: [

“Stream=//DEPOT/STREAM”,

“Platform=Win64”,

“Configuration=Development”,

“ArchiveType=Editor”

],

“namespaceId”: “horde-artifacts”,

“refName”: “ugs-pcb/depot-stream/88849/editor-win64-development/67eabaf9a5469ad837f2e9a3”,

“createdAtUtc”: “2025-03-31T15:55:37Z”

}` But UGS says there aren’t any binaries to sync. Am I missing some kind of setup in UnrealGameSync.ini or in Horde?

I’ve tried looking through the UnrealGameSync source as much as possible but I can’t seem to find anything that would be preventing the above from working.

I did find this line in ArchiveInfo.cs **// Where to find archives, you’ll have either Perforce (DepotPath) or Horde (ArchiveType)**, but I don’t see anything about this ArchiveType being referenced here.

Previous P4 setup in UnrealGameSync.ini:

`[//Depot/Stream/Project/Project.uproject]

+Archives=(Name=“P4”, DepotPath=“//Depot/EditorStream/++Depot+Stream-ProjectEditor.zip”)`Any help would be appreciated, thanks.

Steps to Reproduce

Hey there Liam,

So it appears that you’ve verified you’re pushing the ugs-pcb up correctly (assuming you’ve verified via the swagger/index.html; alternatively the Tools -> Artifacts view in Horde web browser).

Next you’ll need to make sure you’re connected to your horde server:

  • From UGS -> Click options (Bottom right of UGS) -> Application Settings
  • Confirm your horde server is correct
    • If not, modify, and you’ll be asked to restart
  • Upon restart; you should be able to see at the very top of the project that’s open a “Connect to horde” (if not connected already); click this to connect
  • Then you can go back into your Options -> Sync Precompiled Binaries -> select your editor here (whatever you’ve named it with description in your publish step)

Let me know if this helps. I must note, I’ve seen some of the changelists that do have artifacts for ugs-pcb not being syncable in UGS.

Edit: So the changelists that were removed on my end were due to the RequiredBadges set in the UnrealGameSync.ini - so unless you’ve specified this, you won’t hit this issue.

Julian

Hi Liam.

Everything looks correct to my reading from the Horde api. I’d suggest attaching a debugger to your UGS instance, and stepping through these two key points:

  • Place a breakpoint within CanSyncChange (WorkspaceControl.cs)
    • Conditional breakpoint on a changelist you know to have a PCB - so 85255 in your team’s case
    • Click on that row (it would be greyed out); step through and confirm that there are available channels
      • Debugging into GetSelectedArchiveChannels can help show whether the channels are even being connected
      • It’s worth noting that UpdateArchivesAsync should be invoked when you update your sync precompiled binaries (shown below); if you don’t see anything here this should help narrow in.

Also, when referring to connection I am specifically stating this mechanism:

[Image Removed]- it can be slightly confusing in that the ugs api is used explicitly for a separate functionality (metadata server).

When referring to the options -> sync precompiled binaries dropdown:

[Image Removed]

Julian

I can’t seem to get my debugger to attach to WorkspaceControl.cs. This includes both trying to attach to my actual UnrealGameSync instance, as well as compiling my own from source and debugging that. Other parts of UnrealGameSync is debuggable but that file in particular doesn’t seem to like it.

Additionally, I have no options under Sync Precompiled Binaries. It is completely greyed out.

I also decided to attach to my Horde Server instance too to see if that would pick anything up. It gets hit when using the Swagger API but never gets hit when using UGS.

Hey Liam.

It seems that no channels are coming through then, if you’re Sync Precompiled Binaries has no options (or is it just greyed out?). I’d recomend trying to step through “UpdateArchivesAsync” in Perforce Monitor, to see what’s going on with your channels. If you’re getting none, stepping through the EnumerateChannelsAsync could point us in the direction of what’s going wrong.

Julian

[mention removed]​ One thing to keep in mind is that getting badges from horde after setting up https://horde.example.com/ugs in UnrealGameSync.ini is not same as UGS actually connected to Horde. As [mention removed]​ mentioned you need to make sure horde url is setup in UGS Application Settings and make sure UGS auths with Horde by opening browser, if its not connected to Horde there will be Connect to Horde… text before Settings… If UGS is actually connected you should see “Connected to Horde” on UGS.

[Image Removed]

>I think one of the issues was due to using a modified version of UGS. I have a clean version of UGS from 5.5.4 that I am using and I can now debug it and it seems to trigger certain steps it didn’t before.

Ah yes, that’ll do it…

How is your current Horde authentication configured? Also do you have a UGS log handy?

Regards,

Julian

I think one of the issues was due to using a modified version of UGS. I have a clean version of UGS from 5.5.4 that I am using and I can now debug it and it seems to trigger certain steps it didn’t before.

However, a problem I am facing now is that in HordeHttpClient.cs:237, I get an Unauthorised Response when it tries to get the artifact, despite being ‘Connected to Horde’.

FindArtifactsResponse response = await GetAsync<FindArtifactsResponse>(_httpClient, $"api/v2/artifacts?{queryParams}", cancellationToken);It works fine in my browser.

Hey Liam!

It should be located under: C:\Users\${USER_NAME}\AppData\Local\UnrealGameSync\.

Ok this is interesting - do you have your acl configuration?

Regarding OIDC changes, it could very well be related as this has been an area of much improvement. [mention removed]​ - do you have any thoughts or does this ring a bell?

Julian

The error [Bearer, Bearer error=“invalid_token”, error_description=“The signature is invalid”] makes me think it’s an issue with how UGS is getting the access token rather than the ACL setup on the Horde side.

That second GitHub change looks like it’s in a very related area so I can follow up with some of our devs next week to double check if it could potentially fix this issue.

If not we can further investigate why the token might be invalid as it’s something that has come up before.

But as Julian says, please do check the UGS logs just in case there is any other info that might be able to help us out here.

Hi Liam,

For completeness, could you please upload as an attachment the entire log, so we can have it ready for the team.

Kind regards,

Julian

I also tried downloading a Horde Artifact via UGS with a .uartifact file.

UGS opened and it said Connecting to server for quite some time before finally throwing this message.

I’m assuming it’s related.

[Image Removed]

I have tried messing around with the Insomnia REST client to help see what’s going on.

GET https://horde01.domain.com/api/v2/artifacts?type=ugs-pcb&key=ugs-project%3D%2F%2FDepot%2FRND1Merge%2FDemo1%2FDemo1.uproject&maxResults=100

It gives me 401 Unauthorised and gives me some info to try to login, including location with a URL to https://login.microsoftonline.com/…, as well as some cookies to try to login.

However, when I do try to change the URL to https://login.microsoftonline.com/ with the set cookies, I get to this page.

[Image Removed]

However, entering this URL into my web browser redirects me to my Horde server under horde01.domain.com/signin-oidc with the following message:

{ "time": "2025-04-24T13:55:23", "level": "Error", "message": "Unhandled exception: An error was encountered while handling the remote login.", "format": "Unhandled exception: {Message}", "properties": { "Message": "An error was encountered while handling the remote login." }, "exception": { "message": "An error was encountered while handling the remote login.", "trace": " at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler1.HandleRequestAsync()\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.\u003CInvoke\u003Eg__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)",
“innerException”: {
“message”: “Correlation failed.”,
“trace”: “”,
“innerExceptions”:
},
“innerExceptions”:
}
}`

I just tried it again in a fresh browser session.

Get artifacts gives me 401, but when I copy the location it tells me to login, it does actually end up logging me in and shows me the correct artifacts.

Could the issue in this case be to do with Horde not sending by a proper redirect request?

I attempted to make a change to UGS so it uses a clean HTTP Client and handles the initial redirection to Microsoft for me, but it still fails to continue the auth flow after the Microsoft page.

Hey there Liam,

I’ve corresponded with the SME for auth.

  1. I would expect UGS to resolve a token through OIDC first. Is that even happening?
  2. Are URLs being mixed http:// and https:// for URLs? Both in config for Unreal tools and redirect URLs configured in the Azure OIDC app?
  3. Are the certs self-signed or proper certs?
  4. Turning on OIDC debug logging on the server would be helpful, and see if there’s anything useful logged.

Julian

Hi Liam,

Thanks. Please update us with the logs with OIDC being enabled.

Julian

Hi Julian,

Thanks for the response. However, I am already connected to Horde under https://HordeServer.com/ugs (I have also tried it without the /ugs path in case that was causing the issue). It is also set in UnrealGameSync.ini under:

[Default] ApiUrl=https://HordeServer.com/ugsAll the UGS badges from Build Graph and the rest of the UGS metadata server is working as expected. I also do not have anything to do with Required Badges set anywhere.

Swagger provides me these results:

Request:

curl -X 'GET' \ 'https://HordeServer.com/api/v2/artifacts?type=ugs-pcb&key=ugs-project%3D%2F%2Fdepot%2Fstream%2Fproject%2Fproject.uproject&maxResults=100' \ -H 'accept: text/plain'Response:

{ "artifacts": [ { "id": "67eabaf9a5469ad837f2e9a3", "name": "editor-win64-development", "type": "ugs-pcb", "description": "Editor Win64", "streamId": "depot-stream", "change": 88849, "commitId": { "name": "88849", "order": 88849 }, "keys": [ "job:67eab7d9a5469ad837f29d18", "job:67eab7d9a5469ad837f29d18/step:0dfe", "ugs-project=//depot/stream/project/project.uproject" ], "metadata": [ "Stream=//Depot/Stream", "Platform=Win64", "Configuration=Development", "ArchiveType=Editor" ], "namespaceId": "horde-artifacts", "refName": "ugs-pcb/depot-stream/88849/editor-win64-development/67eabaf9a5469ad837f2e9a3", "createdAtUtc": "2025-03-31T15:55:37Z" }, { "id": "67eab35ea5469ad837f1f9a9", "name": "editor-win64-development", "type": "ugs-pcb", "description": "Editor Win64", "streamId": "depot-stream", "change": 88841, "commitId": { "name": "88841", "order": 88841 }, "keys": [ "job:67eaafa5a5469ad837f1bea9", "job:67eaafa5a5469ad837f1bea9/step:1440", "ugs-project=//depot/stream/project/project.uproject" ], "metadata": [ "Stream=//Depot/Stream", "Platform=Win64", "Configuration=Development", "ArchiveType=Editor" ], "namespaceId": "horde-artifacts", "refName": "ugs-pcb/depot-stream/88841/editor-win64-development/67eab35ea5469ad837f1f9a9", "createdAtUtc": "2025-03-31T15:23:10Z" }, { "id": "67b354de8433d8223961bf51", "name": "editor", "type": "ugs-pcb", "description": "Editor PCBs", "streamId": "depot-stream", "change": 85255, "commitId": { "name": "85255", "order": 85255 }, "keys": [ "job:67b353d48433d8223961ba2e", "job:67b353d48433d8223961ba2e/step:1094", "ugs-project=//depot/stream/project/project.uproject" ], "metadata": [ "ArchiveType=Editor" ], "namespaceId": "horde-artifacts", "refName": "ugs-pcb/depot-stream/85255/editor/67b354de8433d8223961bf51", "createdAtUtc": "2025-02-17T15:25:18Z" } ] }

Hi, I can confirm it does say Connected to Horde at the top of UGS.

Hi, we are using OpenIDConnect as our authentication for Horde. Everything else seems to work fine except for grabbing artifacts via UGS.

Where are log files stored for UGS?

This was the access token used in the request:

{ "aud": "00000003-0000-0000-c000-000000000000", "iss": "https://sts.windows.net/87fb0ec9-127b-4e4b-ba4d-aacb35cd29f2/", "iat": 1744899625, "nbf": 1744899625, "exp": 1744904529, "acct": 0, "acr": "1", "acrs": [ "p1" ], "aio": "AXQAi/8ZAAAAlkqxyaMVYRkL3bSWqpEA/fRrFaSWYE7VBKuNwDmDT1KVJECJk9U/e1AJHnoRxXuonmBMYAVrXpZm5q1LwiETKKr8LdWqyfSRq7oAq5wODnFVRf3DvxhE8xE77mS+DyId/739PrR1YEkTBHbktrG8aw==", "amr": [ "pwd", "rsa", "mfa" ], "app_displayname": "RHorde01", "appid": "ef9ecc72-b205-4c3c-977c-70b4c99e8ab5", "appidacr": "0", "deviceid": "da96a1eb-60b1-40d8-89e8-b52ca428c78a", "family_name": "Hall", "given_name": "Liam", "idtyp": "user", "ipaddr": "195.188.xxx.xx", "name": "Liam Hall", "oid": "6b16234f-04aa-4c50-9d23-5853e13a2f01", "onprem_sid": "S-1-5-21-3345621451-883145605-340182576-44639", "platf": "3", "puid": "10032002C7437CA1", "rh": "1.AXQAyQ77h3sSS066TarLNc0p8gMAAAAAAAAAwAAAAAAAAAB0ANF0AA.", "scp": "email openid profile User.Read User.Read.All", "sid": "360ca47c-15e5-4fec-b3d4-4848a23b007b", "signin_state": [ "dvc_mngd", "dvc_dmjd", "inknownntwk", "kmsi" ], "sub": "Ufi3t8rfHWrk-Px3CxqfqMZQAGH84xgux36yg3ixf6I", "tenant_region_scope": "EU", "tid": "87fb0ec9-127b-4e4b-ba4d-aacb35cd29f2", "unique_name": "l.hall[Content removed] "upn": "l.hall[Content removed] "uti": "DTtjW6jo0EOBGyXl3IHwAA", "ver": "1.0", "wids": [ "b79fbf4d-3ef9-4689-8143-76b194e85509" ], "xms_ftd": "V1IVyg1PpsVAhflqdONLzFj7ioMWjsdbFMPZsufw7RU", "xms_idrel": "12 1", "xms_st": { "sub": "uXBvnAL9_DpyF4K1Yii1a2SFFn2IzfnrKCxgo8g4ryM" }, "xms_tcdt": 1425245060 }

The response also contains a WWW-Authenticate header that looks like ‘Bearer, Bearer error=“invalid_token”, error_description=“The signature is invalid”’

I’ve noticed UE-main on GitHub has a few changes relating to OIDC and mentions UGS. Could these include the necessary fixes?

https://github.com/EpicGames/UnrealEngine/commit/bbfa53716e96a9ddfa48cd3943a59b29dcc64579

https://github.com/EpicGames/UnrealEngine/commit/0ba2e7e4bc5fb440baa839b5db990dbf9a464c71