wailsapp/wails · error

CreateStreamOnHGlobal failed with E_OUTOFMEMORY

Error message

CreateStreamOnHGlobal failed with E_OUTOFMEMORY

What it means

CreateStreamOnHGlobal returned E_OUTOFMEMORY: the system could not allocate the internal stream object (or lock the global memory) because memory is exhausted. The Go wrapper panics on this HRESULT. It is an environment/resource condition, not an argument mistake.

Source

Thrown at v3/pkg/w32/ole32.go:85

	case E_UNEXPECTED:
		panic("CoCreateInstance failed with E_UNEXPECTED")
	}

	return HRESULT(ret)
}

func CreateStreamOnHGlobal(hGlobal HGLOBAL, fDeleteOnRelease bool) *IStream {
	stream := new(IStream)
	ret, _, _ := procCreateStreamOnHGlobal.Call(
		uintptr(hGlobal),
		uintptr(BoolToBOOL(fDeleteOnRelease)),
		uintptr(unsafe.Pointer(&stream)))

	switch uint32(ret) {
	case E_INVALIDARG:
		panic("CreateStreamOnHGlobal failed with E_INVALIDARG")
	case E_OUTOFMEMORY:
		panic("CreateStreamOnHGlobal failed with E_OUTOFMEMORY")
	case E_UNEXPECTED:
		panic("CreateStreamOnHGlobal failed with E_UNEXPECTED")
	}

	return stream
}
func OleInitialise() {
	procOleInitialize.Call()
}

func RegisterDragDrop(hwnd HWND, dropTarget *DropTarget) error {

	dt := combridge.New[iDropTarget](dropTarget)
	hr, _, _ := procRegisterDragDrop.Call(
		hwnd,
		dt.Ref(),
	)

View on GitHub (pinned to 0e754b1b40)

Solutions

  1. Free memory: make sure every IStream from this path gets Release()d and the corresponding HGLOBAL is owned correctly
  2. Reduce payload size or stream data in chunks instead of one giant HGLOBAL
  3. Check available memory / switch to a 64-bit build if running 32-bit
  4. Recover from the panic at the operation boundary and surface an 'out of memory' error to the user instead of crashing the app
Defensive patterns

Strategy: retry

Validate before calling

var ms memoryStatus
GlobalMemoryStatusEx(&ms)
if ms.AvailPhys < uint64(size) {
    return fmt.Errorf("insufficient memory for %d bytes", size)
}

Try / catch

for attempt := 0; attempt < 2; attempt++ {
    func() (err error) {
        defer func() { if r := recover(); r != nil { err = fmt.Errorf("stream alloc failed: %v", r) } }()
        stream = w32.CreateStreamOnHGlobal(h, true)
        return
    }()
    if err == nil { break }
    runtime.GC() // release unreferenced streams, then retry once
}

Prevention

When it happens

Trigger: Large payloads placed on the clipboard or drag-drop data object on a memory-pressured machine; a leak of IStream objects (never Released) gradually exhausting the heap; committing a very large HGLOBAL.

Common situations: Long-running Wails processes that repeatedly build streams for clipboard/drag operations without Release(); containers or CI runners with tight memory limits; 32-bit processes hitting the 2GB address-space ceiling.

Related errors


AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15). Data as JSON: /api/errors/571cce906f108278. Report an issue: GitHub.