2026.2.1 — Endpoint URL validation false positive: static URL rejected when a parameterized route shares the same prefix ("It matches an existing internal URL")

A fix for this issue has been implemented in version 2026.2.2
Implemented

2026.2.1 — Endpoint URL validation false positive: static URL rejected when a parameterized route shares the same prefix ("It matches an existing internal URL")

avatar

Product: PowerShell Universal 2026.2.1 (upgraded from 2026.1.1 — issue does not exist on 2026.1.1)
Environment: Linux (Docker), multi-node, PostgreSQL, configuration as code (git-synced .universal repository)

Summary
Since upgrading to 2026.2.1, endpoint URL validation rejects a static endpoint URL whenever a parameterized endpoint exists whose path starts with the same segments. The two routes are distinct (different segment counts) and represent the standard REST collection/item pattern (GET /resource + GET /resource/:id). This configuration has been working unchanged since v4 and loads fine on 2026.1.1.

Minimal reproduction
endpoints.ps1:

New-PSUEndpoint -Url "/test" -Method GET -Endpoint { "static" }
New-PSUEndpoint -Url "/test/:param" -Method GET -Endpoint { $Param }


On configuration sync, validation of the static URL fails with:

Endpoint URL /test is not valid. It matches an existing internal URL: GET:/test/:param


Important detail for reproducing this: the error does not necessarily appear on the very first
registration into an empty database. It appears once the parameterized route is already registered —
i.e. on the next configuration sync, after a restart, or when a second node in a multi-node setup
loads the same repository. This may be why issue #5627 (same error class, App URLs) could never be
reproduced in-house.

Real-world error (verbatim)

Invalid configuration: endpoints.ps1
(Endpoint URL /v1/runner/jobs is not valid. It matches an existing internal URL:
POST:/v1/runner/jobs/:jobId/status


at PowerShellUniversal.Configuration.UrlValidator.ValidateStaticUrls[T](T item, String url, String[] methods)
   in src\PowerShellUniversal.Configuration\UrlValidator.cs:line 185
at PowerShellUniversal.Configuration.UrlValidator.Validate(Endpoint endpoint)
   in src\PowerShellUniversal.Configuration\UrlValidator.cs:line 47
at PowerShellUniversal.Configuration.EndpointService.UpdateAsync(ModelOperationContext`1 context)
   in src\PowerShellUniversal.Configuration\Endpoints.cs:line 213
at UniversalAutomation.Services.ConfigurationScript`1.ReadAsync(...)
   in src\PowerShellUniversal\ConfigurationScript.cs:line 461


Our production configuration (unchanged for years):

POST /v1/runner/jobs
GET  /v1/runner/jobs
GET  /v1/runner/jobs/:jobId
POST /v1/runner/jobs/:jobId/status
GET  /v1/runner/jobs/:jobId/status
...


Note that /v1/runner/jobs (3 segments) is reported as "matching"
POST:/v1/runner/jobs/:jobId/status (5 segments). A correct route matcher can never match these two — it looks like `ValidateStaticUrls` truncates parameterized route templates at the first route parameter and then compares the remaining prefix against static URLs.

Knock-on effects
environments.ps1 is marked invalid with the same error, because the environments sync re-triggers endpoint validation:

at PowerShellUniversal.Configuration.EnvironmentsConfigurationScript.OnReadAfterAllAsync(SyncContext syncContext) in src\PowerShellUniversal.Configuration\Environments.cs:line 43


So a single validation false positive invalidates both the endpoints and the environments configuration — the entire custom REST API is down. In our case several hundred deployed agents lost connectivity after the upgrade; this is a hard outage for us.

What we tried

  • Curly-brace syntax (/test/{param}) instead of :param — not supported, does not work.
  • Reordering the endpoint definitions — no effect (validation compares against routes already registered from the previous sync / the other node).
  • Looked for a setting to disable or relax endpoint URL validation — none exists as far as we can tell (neither in appsettings.json nor in the feature flags).
  • Merging the two routes into a single endpoint is not possible: an endpoint has exactly one URL, and /test must remain directly callable.
  • Renaming routes so that no static URL is a prefix of a parameterized one would break all deployed API clients — not feasible.


Expected behavior
A static URL should only be rejected when it actually conflicts with an existing route (same method and same path shape/segment count) — as was the case up to and including 2026.1.1.

Related

  • https://github.com/ironmansoftware/powershell-universal/issues/5627 — same error class for App URLs ("was working for years"), closed unresolved when the repo was archived. The reproduction above is deterministic and should finally make this debuggable.
  • The validator appears to have been introduced with the CVE-2026-3563 fix (advisory DEVO-2026-0008) in 2026.1.4. We jumped from 2026.1.1 directly to 2026.2.1, so this validation ran against our repository for the first time.


Questions

  1. Can the false positive in UrlValidator.ValidateStaticUrls be fixed so that the standard REST pattern (GET /resource + GET /resource/:id) validates correctly again?
  2. Until a fix ships: is there any supported way to bypass or relax endpoint URL validation? We are currently blocked from running 2026.2.x at all.

All Comments (1)

avatar

Hi @Andreas,

We are aware of this issue and moving a fix through QA right now. As it stands, we haven't found a workaround and it is why we are fast tracking a release with a fix for this. We've been able to validate the fix resolves the other customer's issue.

Your analysis is correct in that the child URL blocks the registration of the parent URL. 2026.2.2 will be out this week with a fix for it.

Adam Driscoll
PowerShell Expert and Developer at Devolutions

A fix for this issue has been implemented in version 2026.2.2