java-native-access/jna · error · RuntimeException

Service stop exceeded timeout time of

Error message

Service stop exceeded timeout time of %d ms

What it means

W32Service.stopService() polls the service status in a loop until it reports SERVICE_STOPPED. If the wall-clock time since the stop request exceeds the caller-supplied timeout while the service is still not STOPPED, it throws this RuntimeException so the caller knows the stop did not complete in time.

Solutions

  1. Increase the timeout argument to stopService to a value larger than the service's realistic shutdown time.
  2. Fix the service itself so its stop handler exits promptly (signal worker threads, use a cancellation mechanism).
  3. Check the service state manually (sc query / services.msc) to see whether it is stuck in STOP_PENDING and needs force-kill.
  4. Catch the RuntimeException and fall back to killing the process or waiting longer with a fresh request.

Example fix

// before
service.stopService(1000);
// after
service.stopService(60_000); // allow slow shutdowns
Defensive patterns

Strategy: try-catch

Validate before calling

Winsvc.SERVICE_STATUS st = service.queryStatus();
if (st.dwCurrentState == Winsvc.SERVICE_STOPPED) { /* already stopped */ }
// choose timeout generously, e.g. max(30s, 2 * st.dwWaitHint)

Try / catch

try {
    service.stopService(timeoutMs);
} catch (RuntimeException e) {
    Winsvc.SERVICE_STATUS st = service.queryStatus();
    if (st.dwCurrentState != Winsvc.SERVICE_STOPPED) { /* escalate: kill or alert */ }
}

Prevention

When it happens

Trigger: Calling stopService(timeoutMs) on a Windows service whose dwCurrentState stays non-STOPPED past the deadline — e.g. a service with a long OnStop handler, a hung/stuck service, or a timeout set too short for the service's shutdown work.

Common situations: Services that block shutdown waiting on worker threads or network I/O; SCM wait-hint values that understate real stop time; passing small (e.g. 1000 ms) timeouts to services that take tens of seconds to stop; debugging services in a paused or stop-pending state.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/W32Service.java:244

    public void stopService(long timeout) {
        long startTime = System.currentTimeMillis();
        waitForNonPendingState();
        // If the service is already stopped - return
        if (queryStatus().dwCurrentState == Winsvc.SERVICE_STOPPED) {
            return;
        }
        SERVICE_STATUS status = new SERVICE_STATUS();
        if (!Advapi32.INSTANCE.ControlService(_handle, SERVICE_CONTROL_STOP, status)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
        // This following the sample from the MSDN
        // the previouos implementation queried the service status and
        // failed if the application did not correctly update its state
        while (status.dwCurrentState != Winsvc.SERVICE_STOPPED) {
            long msRemainingBeforeTimeout = timeout - (System.currentTimeMillis() - startTime);

            if (msRemainingBeforeTimeout < 0) {
                throw new RuntimeException(String.format("Service stop exceeded timeout time of %d ms", timeout));
            }

            long dwWaitTime = Math.min(sanitizeWaitTime(status.dwWaitHint), msRemainingBeforeTimeout);

            try {
                Thread.sleep(dwWaitTime);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (!Advapi32.INSTANCE.QueryServiceStatus(_handle, status)) {
                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
            }
        }
    }

    /**
     * Continue service.
     */

View on GitHub (pinned to d036ad9781)