jenkinsci/jenkins · critical · IOException

Failed to exec '{exe}' {LIBC.strerror(Native.getLastError())

Error message

Failed to exec '{exe}' {LIBC.strerror(Native.getLastError())}

What it means

Thrown immediately after LIBC.execvp() in UnixLifecycle.restart(). execvp only returns on failure (a successful exec replaces the process image), so reaching this line means the exec system call failed. The message includes the executable path and the C-level errno string from Native.getLastError(). This is a hard restart failure — the current process is still alive but the restart did not happen.

Source

Thrown at core/src/main/java/hudson/lifecycle/UnixLifecycle.java:85

            if (jenkins != null) {
                jenkins.cleanUp();
            }
        } catch (Throwable e) {
            LOGGER.log(Level.SEVERE, "Failed to clean up. Restart will continue.", e);
        }

        // close all files upon exec, except stdin, stdout, and stderr
        int sz = LIBC.getdtablesize();
        for (int i = 3; i < sz; i++) {
            int flags = LIBC.fcntl(i, F_GETFD);
            if (flags < 0) continue;
            LIBC.fcntl(i, F_SETFD, flags | FD_CLOEXEC);
        }

        // exec to self
        String exe = args.getFirst();
        LIBC.execvp(exe, new StringArray(args.toArray(new String[0])));
        throw new IOException("Failed to exec '" + exe + "' " + LIBC.strerror(Native.getLastError()));
    }

    @Override
    public void verifyRestartable() throws RestartNotSupportedException {
        if (!Functions.isGlibcSupported()) {
            throw new RestartNotSupportedException("Restart is not supported on platforms without libc");
        }

        // see http://lists.apple.com/archives/cocoa-dev/2005/Oct/msg00836.html and
        // http://factor-language.blogspot.com/2007/07/execve-returning-enotsup-on-mac-os-x.html
        // on Mac, execv fails with ENOTSUP if the caller is multi-threaded, resulting in an error like
        // the one described in http://www.nabble.com/Restarting-hudson-not-working-on-MacOS--to24641779.html
        //
        // according to http://www.mail-archive.com/wine-devel@winehq.org/msg66797.html this now works on Snow Leopard
        if (Platform.isDarwin() && !Platform.isSnowLeopardOrLater())
            throw new RestartNotSupportedException("Restart is not supported on Mac OS X");
    }

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Check the errno string in the message — ENOENT means the exe path is gone, EACCES means a permission problem
  2. Ensure the java executable and jenkins.war paths used at launch still exist and are executable
  3. Restart Jenkins manually from the correct launch command
  4. Pin the launch script to absolute paths so the exe does not depend on PATH resolution
Defensive patterns

Strategy: try-catch

Validate before calling

String exe = ProcessHandle.current().info().command().orElse(null);
if (exe == null || !new File(exe).canExecute()) {
    throw new IllegalStateException("Launch executable not resolvable/executable: " + exe);
}

Try / catch

try {
    Lifecycle.get().restart();
} catch (IOException e) {
    if (e.getMessage().startsWith("Failed to exec")) {
        // exec failed; parse errno, check exe path, restart manually
    }
    throw e;
}

Prevention

When it happens

Trigger: UnixLifecycle.restart() builds the argv (args list) from the original launch command, closes all file descriptors >= 3 with FD_CLOEXEC, then calls execvp(exe, argv). If exe does not exist, is not executable, or has a permission/ENOEXEC issue, execvp fails and this IOException is thrown.

Common situations: The original java executable or jenkins.war was moved/renamed after Jenkins started; running from a path on a filesystem that has since been unmounted; incorrect exec permissions on the java binary; a misconfigured JAVA_HOME that no longer resolves; running on a read-only filesystem.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/a9caab2d6a5cee4e. Report an issue: GitHub.