java-native-access/jna · error · com.sun.jna.platform.win32.COM.COMException

getUnknownId: <formatMessageFromHR>

Error message

getUnknownId: <formatMessageFromHR>

What it means

This COMException is thrown by ProxyObject.getUnknownId() when the underlying COM call to obtain the IUnknown identifier fails with a non-zero HRESULT. The library appends the human-readable Windows error message (via Kernel32Util.formatMessage) to help identify the exact COM failure. It signals that the proxy could not retrieve or negotiate the IUnknown pointer for the wrapped COM object.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java:120

            try {
                final PointerByReference ppvObject = new PointerByReference();

                Thread current = Thread.currentThread();
                String tn = current.getName();

                IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN;
                HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID(iid), ppvObject);

                if (WinNT.S_OK.equals(hr)) {
                    Dispatch dispatch = new Dispatch(ppvObject.getValue());
                    this.unknownId = Pointer.nativeValue(dispatch.getPointer());
                    // QueryInterface returns a COM object pointer with a +1
                    // reference, we must drop one,
                    // Note: createProxy adds one;
                    int n = dispatch.Release();
                } else {
                    String formatMessageFromHR = Kernel32Util.formatMessage(hr);
                    throw new COMException("getUnknownId: " + formatMessageFromHR, hr);
                }
            } catch (RuntimeException e) {
                // Do not rewrap COMException
                if (e instanceof COMException) {
                    throw e;
                } else {
                    throw new COMException("Error occured when trying get Unknown Id ", e);
                }
            }
        }
        return this.unknownId;
    }

    @Override
    protected void finalize() throws Throwable {
        this.dispose();
        super.finalize();
    }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Ensure COM is initialized on the calling thread (COMUtils.comIsInitialized) and use the object from the thread/apartment that created it
  2. Wrap calls in the handler utilities provided (com.sun.jna.platform.win32.COM.util.HandlerUtil) which marshal calls to the creating thread
  3. Catch COMException and inspect getHresult() to identify the specific Windows error code
  4. Release and re-create the proxy if the underlying COM object was freed

Example fix

// before
Object id = proxy.getUnknownId(); // throws if called off-apartment
// after
if (COMUtils.comIsInitialized()) {
    Object id = HandlerUtil.getObjectIdentity(handler); // marshals to owner thread
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!COMUtils.comIsInitialized()) { throw new IllegalStateException("COM not initialized on this thread"); }

Type guard

boolean usable = proxy != null && COMUtils.comIsInitialized();

Try / catch

try { Object id = proxy.getUnknownId(); } catch (COMException e) { LOG.error("getUnknownId failed hr=0x" + Integer.toHexString(e.getHresult().intValue()), e); }

Prevention

When it happens

Trigger: The raw dispatch.QueryInterface(IUnknown) or related COM call returns a failed HRESULT; the COM object has been released from another thread (RCW released) or its apartment (STA/MTA) requirements are violated.

Common situations: Calling proxy methods from a thread that is not the COM apartment owner; the underlying COM server crashed or released the object; cross-apartment marshaling without proper initialization (CoInitialize missing).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/be2038e6bb62d7a2. Report an issue: GitHub.