java-native-access/jna · error · RuntimeException

Failed to access the print server

Error message

Failed to access the print server - <errorCode>

What it means

Win32SpoolMonitor.monitorAllPrinters() opens a handle to the local print server by calling OpenPrinter with a null printer name. If OpenPrinter fails, the last error code is read and a RuntimeException is thrown with the message 'Failed to access the print server - <errorCode>'. The monitor cannot attach to the spooler at all.

Solutions

  1. Check the errorCode: 5 (ERROR_ACCESS_DENIED) means run elevated or grant the account print-server permissions; 1722/RPC errors mean the spooler is unreachable.
  2. Start the Print Spooler service (net start spooler).
  3. Run the monitor in an interactive session or as a service account with print-operator rights.
  4. Catch the RuntimeException and degrade gracefully instead of crashing the demo/main flow.

Example fix

// before
Winspool.INSTANCE.OpenPrinter(null, printServerHandle, null);
// after
boolean success = Winspool.INSTANCE.OpenPrinter(null, printServerHandle, null);
if (!success) {
    int err = Kernel32.INSTANCE.GetLastError();
    if (err == W32Errors.ERROR_ACCESS_DENIED) {
        LOG.error("Run elevated or grant print-server access to this account");
    }
    return;
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean canOpenPrintServer() {
    HANDLEByReference h = new HANDLEByReference();
    boolean ok = Winspool.INSTANCE.OpenPrinter(null, h, null);
    if (ok) { Winspool.INSTANCE.ClosePrinter(h.getValue()); }
    return ok;
}

Try / catch

try {
    monitor.monitorAllPrinters();
} catch (RuntimeException e) {
    LOG.error("Print-server access failed: " + e.getMessage()
        + " (run elevated / start spooler)");
}

Prevention

When it happens

Trigger: OpenPrinter(null, ...) returning FALSE, typically because the process has no permission to open the print server or the spooler service is not running.

Common situations: Running without administrator/elevated rights in a non-interactive session; Print Spooler service stopped; restricted service accounts lacking server-level printer access.

Related errors


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

Appendix: source

Thrown at contrib/w32printing/src/com/sun/jna/platform/win32/Win32SpoolMonitor.java:104

    }

    public int getLastError() {
        int rc = Kernel32.INSTANCE.GetLastError();

        if (rc != 0)
            System.out.println("error: " + rc);

        return rc;
    }

    public void monitorAllPrinters() {
        System.out.println("Monitoring all printers, press Ctrl + C to stop");
        HANDLEByReference printServerHandle = new HANDLEByReference();
        boolean success =
            Winspool.INSTANCE.OpenPrinter(null, printServerHandle, null);
        if (!success) {
            int errorCode = Kernel32.INSTANCE.GetLastError();
            throw new RuntimeException("Failed to access the print server - " +
                errorCode);
        }

        try {
            PRINTER_NOTIFY_OPTIONS options = new PRINTER_NOTIFY_OPTIONS();
            options.Count = 1;
            PRINTER_NOTIFY_OPTIONS_TYPE.ByReference optionsType =
                new PRINTER_NOTIFY_OPTIONS_TYPE.ByReference();
            optionsType.Type = JOB_NOTIFY_TYPE;
            optionsType.setFields(new short[] {
                JOB_NOTIFY_FIELD_PRINTER_NAME,
                JOB_NOTIFY_FIELD_STATUS,
                JOB_NOTIFY_FIELD_DOCUMENT
            });
            optionsType.toArray(1);
            options.pTypes = optionsType;
            HANDLE changeNotificationsHandle =
                Winspool.INSTANCE.FindFirstPrinterChangeNotification(

View on GitHub (pinned to d036ad9781)