dotnet/runtime · error

Base address must be 0x10000-aligned

Error message

Base address must be 0x10000-aligned

What it means

The `/BAS=<addr>` (image base) switch (main.cpp:492) parses a 64-bit value and then checks `g_stBaseAddress & 0xFFFF`; if any of the low 16 bits are set the address is not 64KiB-aligned and ilasm prints this, going to InvalidOption unless OnErrGo is set. PE image bases must fall on a 64KiB boundary.

Source

Thrown at src/coreclr/ilasm/main.cpp:495

                    {
                        WCHAR *pStr = EqualOrColon(argv[i]);
                        if(pStr == NULL) goto InvalidOption;
                        pStr++;
                        const CHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? "%x" : "%d";
                        NarrowForNumberParsing str{pStr};
                        if(sscanf_s(str,pFmt,&g_dwComImageFlags)!=1) goto InvalidOption;
                    }
                    else if (!_stricmp(szOpt, "BAS"))
                    {
                        WCHAR *pStr = EqualOrColon(argv[i]);
                        if(pStr == NULL) goto InvalidOption;
                        pStr++;
                        const CHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? "%llx" : "%lld";
                        NarrowForNumberParsing str{pStr};
                        if(sscanf_s(str,pFmt,&g_stBaseAddress)!=1) goto InvalidOption;
                        if(g_stBaseAddress & 0xFFFF)
                        {
                            fprintf(stderr,"\nBase address must be 0x10000-aligned\n");
                            if(!pAsm->OnErrGo) goto InvalidOption;
                        }
                    }
                    else if (!_stricmp(szOpt, "STA"))
                    {
                        WCHAR *pStr = EqualOrColon(argv[i]);
                        if(pStr == NULL) goto InvalidOption;
                        pStr++;
                        const CHAR *pFmt = ((*pStr=='0')&&(*(pStr+1) == 'x'))? "%x" : "%d";
                        NarrowForNumberParsing str{pStr};
                        if(sscanf_s(str,pFmt,&g_stSizeOfStackReserve)!=1) goto InvalidOption;
                    }
#ifdef _SPECIAL_INTERNAL_USE_ONLY
                    else if (!_stricmp(szOpt, "TES"))
                    {
                        WCHAR *pStr = EqualOrColon(argv[i]);
                        if(pStr == NULL) goto InvalidOption;
                        pStr++;

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Round the base address up to the next 0x10000 multiple (e.g. `/BAS=0x400000`).
  2. Omit `/BAS` to let the linker pick a valid default base.

Example fix

// before
ilasm /BAS=0x401000 foo.il
// after
ilasm /BAS=0x400000 foo.il
Defensive patterns

Strategy: validation

Validate before calling

// Validate /BAS 0x10000-alignment before invoking ilasm.
function validBase(addr) { return (addr & 0xFFFF) === 0; }
if (!validBase(baseAddr)) throw new Error('Base address not 64KiB-aligned: 0x' + baseAddr.toString(16));

Prevention

When it happens

Trigger: Passing `/BAS=` with an address whose low 16 bits are nonzero (e.g. `/BAS=0x401000`).

Common situations: Mistakenly using a 4KiB-aligned address from an ELF context; copy-pasting a hint address that isn't 64KiB-aligned.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/4163a724ce3ed442. Report an issue: GitHub.