GetTokenInformation(TokenHasRestrictions=21) returns ReturnLength=1 despite DWORD documentation

靖智 蘇 0 Reputation points
2026-09-11T09:20:56.7333333+00:00

Subject: GetTokenInformation(TokenHasRestrictions=21) returns ReturnLength=1 despite DWORD documentation

Hello Microsoft Support,

We are requesting clarification regarding the documented contract for GetTokenInformation with TOKEN_INFORMATION_CLASS = TokenHasRestrictions (21).

Microsoft documentation states that the output buffer receives a DWORD value indicating whether the token has ever been filtered.

On our Windows system, we verified the actual provider chain as:

Advapi32.dll → IAT → KERNELBASE.dll

Both modules are Microsoft-signed and pass local trust verification.

Using an independent native query with a DWORD-sized output buffer initialized to:

AA AA AA AA

the call succeeds with:

BOOL = 1

ReturnLength = 1

output bytes:

01 AA AA AA

This shows that only the first byte was modified, while the public documentation describes the output as a DWORD.

Could you please clarify:

  1. Is ReturnLength = 1 with a one-byte output for TokenHasRestrictions (21) an intentional and officially supported compatibility behavior?
  2. If yes, what is the supported caller contract across Windows versions for:
    • minimum output buffer capacity,
      • validation of ReturnLength,
        • decoding the returned value?
        1. Should callers still provide a DWORD-sized buffer even when ReturnLength is reported as 1?
        2. If this behavior is not officially supported, what runtime or provider condition could explain the observed result?

We can provide the exact Windows build, provider file versions, hashes, and a minimal native reproduction if required.

Thank you.

Windows development | Windows API - Win32
0 comments No comments

1 answer

Sort by: Most helpful
  1. Taki Ly (WICLOUD CORPORATION) 4,440 Reputation points Microsoft External Staff Moderator
    2026-09-11T09:50:43.7333333+00:00

    Hello @靖智 蘇 ,

    Thank you for reporting this. I was able to reproduce the same behavior with a minimal native x64 test on Windows build 26200.9168.

    For TokenHasRestrictions, I initialized a four-byte buffer as follows:

    AA AA AA AA
    

    After calling GetTokenInformation, the result was:

    BOOL         = 1
    ReturnLength = 1
    Buffer       = 01 AA AA AA
    

    I also tested buffer sizes from zero through four bytes:

    • With no output buffer, the call failed with ERROR_INSUFFICIENT_BUFFER and reported ReturnLength = 1.
    • A one-byte buffer was sufficient for the call to succeed.
    • With a four-byte buffer, only the first byte was modified.
    • Calling the underlying NtQueryInformationToken API produced the same result.

    This confirms that the behavior is reproducible and is not caused by the original caller's buffer handling.

    However, it does not match the current documentation. Both the Win32 and WDK documentation state that TokenHasRestrictions returns a DWORD. The Windows SDK also classifies it as an ULONG query. Both types are four bytes.

    Therefore, the available evidence shows a genuine inconsistency between the documented contract and the current runtime behavior. I could not find public documentation confirming that the one-byte output is an officially supported compatibility contract across Windows versions.

    For defensive code, I recommend continuing to provide a zero-initialized DWORD-sized buffer, while allowing for the observed one-byte return:

    DWORD value = 0;
    DWORD returnLength = 0;
    
    if (GetTokenInformation(
            token,
            TokenHasRestrictions,
            &value,
            sizeof(value),
            &returnLength)) {
    
        if (returnLength == sizeof(BYTE) ||
            returnLength == sizeof(DWORD)) {
            BOOL hasRestrictions = (value != 0);
        }
    }
    

    Zero-initializing the entire DWORD is important because the tested implementation modifies only the first byte. Supplying only a one-byte buffer is not recommended for portable code because the published contract still specifies a DWORD.

    As this is a community forum, I don't have backend or internal implementation access, so the above is based on public docs and external observation only. An authoritative answer would need confirmation from the Windows API owner via Windows Feedback Hub or a Microsoft support request.

    Hope this helps. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation.

    Thank you.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.