> On Sep 21, 2026, at 6:28 PM, Bryan Green <[email protected]> wrote:
> 
> On 9/21/2026 11:24 AM, Greg Burd wrote:
>> Hi hackers,
>> 
>> My Windows-on-Arm buildfarm animal (unicorn: Windows 11 Pro build 26200.9457,
>> aarch64, MSVC 19.50, meson, cassert) currently fails 13 TAP tests on
>> REL_19_STABLE, and all 13 have the same cause: Windows returns error code 448
>> for stat() on a tablespace path, src/port/win32error.c does not know that 
>> code,
>> and so the error is reported as the catch-all EINVAL ("Invalid argument").
>> 
>> The core regression suite passes (meson check: Ok:1 Fail:0); this is 
>> confined to
>> tests that use tablespaces.
>> 
>> In the logs:
>> 
>>  LOG:    unrecognized win32 error code: 448
>>  ERROR:  could not stat directory "pg_tblspc/16387/PG_19_202609165/5": 
>> Invalid argument
>>  STATEMENT:  CREATE TABLE test1 (a int) TABLESPACE tblspc1;
>> 
>> Error 448 is:
>> 
>>  #define ERROR_UNTRUSTED_MOUNT_POINT 448L        (winerror.h, Windows SDK 
>> 10.0.26100)
>>  448 -> "The path cannot be traversed because it contains an untrusted mount 
>> point"
>> 
>> I think this is a newer Windows hardening behavior around reparse points.  
>> Since
>> PostgreSQL emulates symlinks with junction points 
>> (IO_REPARSE_TAG_MOUNT_POINT)
>> for pg_tblspc, paths under pg_tblspc are subject to it.
>> 
>> So, the mapping below is worth having on its own (an unmapped Win32 code
>> becoming EINVAL is never useful), but I suspect the real fix for tablespaces 
>> on
>> recent Windows is in pgsymlink().  I would appreciate a second opinion from
>> people who know the Windows file-system code better than I do, particularly 
>> on
>> whether populating PrintName is the right move.
>> 
>> Happy to run experiments on this machine.
>> 
>> best.
>> 
>> -greg
> 
> Microsoft has changed what accounts can traverse untrusted junctions in
> it's latest releases.  If you search for openssh and RedirectionGuard
> you will find interesting reading.

Hey Bryan, thanks for replying.

Okay, thanks for the pointer.  I'm not a MS expert, I just try to keep
my buildfarm animal (win11/msvc) mostly healthy.

> The error you are hitting is RedirectionGuard.  PrintName is display
> only. SubstituteName is what resolves the mount point, so populating
> PrintName changes nothing.
> 
> PG does not create trusted junctions. pg_ctl launches the postmaster
> with a restricted token and the backend refuses to run with admin rights
> at all.  So, junctions are created with a non-admin token which makes
> them un-trusted by construction.
> 
> A process that has EnforceRedirectionTrust set refuses to traverse an
> untrusted one and gets 448.  The policy is opt-in, so it is not on by
> default, and it is inherited by children.
> 
> You would need something that is launching the process that has
> RedirectionGuard enabled or that it was opted in for the OS.
> 
> That is also why CI does not catch it.  The GitHub Actions Windows job
> runs on windows-2022, which does not enforce this.  A 26200 animal with
> an enforcing parent (process or OS) does.
> 
> I would check if you are running a non-standard terminal or the
> Win32-Openssh 10.0.0.0-pre2 installer was used on Unicorn.  That
> installer makes ssh.exe enforce redirection trust.  There are ways to
> check if anything in the ancestor chain has that set.

Very helpful, thanks I'll review my setup for the animal I likely have
something wrong there that needs to be adjusted to avoid this issue.

best.

-greg

> 
> --
> Bryan Green
> EDB: https://www.enterprisedb.com




Reply via email to