{"record":{"id":"82eca850b21063b7","repo":"oven-sh/bun","slug":"unexpectedoverlaypresent","errorCode":null,"errorMessage":"UnexpectedOverlayPresent","messagePattern":"UnexpectedOverlayPresent","errorType":"console","errorClass":"bun_exe_format::pe::Error","httpStatus":null,"severity":"error","filePath":"src/exe_format/pe.rs","lineNumber":37,"sourceCode":"    #[error(\"InvalidDOSSignature\")]\n    InvalidDOSSignature,\n    #[error(\"InvalidPESignature\")]\n    InvalidPESignature,\n    #[error(\"UnsupportedPEFormat\")]\n    UnsupportedPEFormat,\n    #[error(\"InsufficientHeaderSpace\")]\n    InsufficientHeaderSpace,\n    #[error(\"TooManySections\")]\n    TooManySections,\n    #[error(\"SectionExists\")]\n    SectionExists,\n    #[error(\"InputIsSigned\")]\n    InputIsSigned,\n    #[error(\"InvalidSecurityDirectory\")]\n    InvalidSecurityDirectory,\n    #[error(\"SecurityDirInsideImage\")]\n    SecurityDirInsideImage,\n    #[error(\"UnexpectedOverlayPresent\")]\n    UnexpectedOverlayPresent,\n    #[error(\"InsufficientSpace\")]\n    InsufficientSpace,\n}\n\n/// Windows PE Binary manipulation for codesigning standalone executables\npub struct PEFile {\n    pub(crate) data: Vec<u8>,\n    // Store offsets instead of pointers to avoid invalidation after resize\n    pub(crate) pe_header_offset: usize,\n    pub(crate) optional_header_offset: usize,\n    pub(crate) section_headers_offset: usize,\n    pub(crate) num_sections: u16,\n}\n\n// PE/COFF on-disk header structs are byte-packed (no padding) per spec, and may\n// live at arbitrary byte offsets inside a `Vec<u8>` image, so `align_of` must be 1\n// for it to be sound to materialize references/pointers to them from the buffer.","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/exe_format/pe.rs#L19-L55","documentation":"After removing the certificate table, bytes still remain beyond the last section's raw-data end (src/exe_format/pe.rs:422-426). Those trailing bytes are an 'overlay' (debug data, appended archives, a second signature) that strip_authenticode did not account for; the injector refuses to proceed because the overlay's meaning is unknown.","triggerScenarios":"`bun build --compile --target=windows` where the base exe has data appended after the last section in addition to (or instead of) the certificate table — e.g. self-extracting installer stubs, bootstrappers that append a ZIP, or PEs with detached debug-directory file content.","commonSituations":"Using installer/SFX stubs or packer output as the compile base; executables with appended .NET native payloads or embedded ZIPs; CI bases processed by tools that append metadata blobs.","solutions":["Use the plain Bun executable as the base — it has no overlay.","Strip the overlay from the custom base: truncate the file to max(section PointerToRawData+SizeOfRawData) with a small script, or use a PE overlay remover tool, then compile.","Confirm with `pefile` (Python) or `dumpbin` that Overlay offset/size are zero after cleaning.","Re-sign the final output (`signtool sign`) after Bun compiles it — signing last avoids the strip path entirely."],"exampleFix":"# before: base has appended overlay -> UnexpectedOverlayPresent\nbun build app.ts --compile --base sfx-stub.exe --target=windows-x64\n# after: truncate overlay, then compile (and re-sign after)\npython -c \"import pefile,os; p=pefile.PE('sfx-stub.exe', fast_load=True); end=max(s.PointerToRawData+s.SizeOfRawData for s in p.sections); os.truncate('clean.exe' if False else 'sfx-stub.exe', end)\"\nbun build app.ts --compile --base sfx-stub.exe --target=windows-x64","handlingStrategy":"fallback","validationCode":"python -c \"\nimport pefile\npe = pefile.PE('base.exe')\nlast = max((s.PointerToRawData + s.SizeOfRawData) for s in pe.sections)\nassert len(pe.__data__) <= last or (pe.OPTIONAL_HEADER.DATA_DIRECTORY[4].VirtualAddress == last), 'unexpected overlay present'\n\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reject installer/SFX stubs and overlay-carrying exes as compile bases","Truncate custom bases to the last section end before compiling","Do post-compile signing so no overlay is ever present at injection time"],"tags":["windows","pe","overlay","compile","standalone"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}