{"record":{"id":"b500332664230fd4","repo":"java-native-access/jna","slug":"win32exception-error-code-from-getlasterror-after-getprinter","errorCode":null,"errorMessage":"Win32Exception (error code from GetLastError after GetPrinter)","messagePattern":"Win32Exception \\(error code from GetLastError after GetPrinter\\)","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java","lineNumber":119,"sourceCode":"        IntByReference pcReturned = new IntByReference();\n        HANDLEByReference pHandle = new HANDLEByReference();\n\n        if (!Winspool.INSTANCE.OpenPrinter(printerName, pHandle, null)) {\n            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n        }\n\n        Win32Exception we = null;\n        PRINTER_INFO_2 pinfo2 = null;\n\n        try {\n            Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, null, 0, pcbNeeded);\n            if (pcbNeeded.getValue() <= 0) {\n                return new PRINTER_INFO_2();\n            }\n\n            pinfo2 = new PRINTER_INFO_2(pcbNeeded.getValue());\n            if (!Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, pinfo2.getPointer(), pcbNeeded.getValue(), pcReturned)) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            pinfo2.read();\n        } catch (Win32Exception e) {\n            we = e;\n        } finally {\n            if (!Winspool.INSTANCE.ClosePrinter(pHandle.getValue())) {\n                Win32Exception ex = new Win32Exception(Kernel32.INSTANCE.GetLastError());\n                if (we != null) {\n                    ex.addSuppressedReflected(we);\n                }\n            }\n        }\n\n        if (we != null) {\n            throw we;\n        }\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java#L101-L137","documentation":"WinspoolUtil.getPrinterInfo2() opens a printer and calls the Win32 GetPrinter API with level 2. If GetPrinter returns FALSE, the native error code from GetLastError is wrapped in a Win32Exception and thrown. This means the printer handle/level/buffer combination was rejected by the spooler.","triggerScenarios":"Calling getPrinterInfo2 with an invalid or closed printer handle, insufficient rights on the printer, or the spooler rejecting the level-2 GetPrinter call after the initial buffer-size call succeeded (e.g. printer deleted or access revoked between the two calls).","commonSituations":"Querying a network printer that has gone offline, running without printer-access privileges (e.g. service account lacking printer permissions), or a race where the printer is removed while the handle is open.","solutions":["Check the Win32Exception's errorCode (e.g. 5 = access denied, 87 = invalid parameter, 1801 = invalid printer name) and fix the underlying cause.","Verify the printer name passed to OpenPrinter is valid and the printer exists (use getPrinterNames/EnumPrinters first).","Run the process under an account with permissions on the target printer; for network printers ensure the spooler is reachable.","Re-check that the printer still exists between the size-query and data call; retry getPrinterInfo2 if the error is transient."],"exampleFix":"// before\nPRINTER_INFO_2 info = WinspoolUtil.getPrinterInfo2(printerName);\n// after\nif (!WinspoolUtil.getPrinterNames().contains(printerName)) {\n    throw new IllegalArgumentException(\"Printer not found: \" + printerName);\n}\ntry {\n    PRINTER_INFO_2 info = WinspoolUtil.getPrinterInfo2(printerName);\n} catch (Win32Exception e) {\n    if (e.getErrorCode() == W32Errors.ERROR_ACCESS_DENIED) {\n        throw new IllegalStateException(\"No permission for printer \" + printerName, e);\n    }\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"boolean printerExists(String name) {\n    return WinspoolUtil.getPrinterNames().stream().anyMatch(n -> n.equalsIgnoreCase(name));\n}","typeGuard":null,"tryCatchPattern":"try {\n    PRINTER_INFO_2 info = WinspoolUtil.getPrinterInfo2(name);\n} catch (Win32Exception e) {\n    switch (e.getErrorCode()) {\n        case 5: throw new SecurityException(\"Access denied for printer \" + name, e);\n        case 1801: throw new IllegalArgumentException(\"Invalid printer name\", e);\n        default: throw e;\n    }\n}","preventionTips":["Validate the printer name against EnumPrinters output before querying.","Check the spooler service status before printer operations.","Run under an account with printer permissions.","Inspect Win32Exception.getErrorCode() and map codes to concrete causes."],"tags":["windows","printing","win32","native"],"backgroundTag":"api-error-response","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}