elastic/elasticsearch · error · GradleException

Failed to read exec output

Error message

Failed to read exec output

What it means

LoggedExec.run() wraps any exception thrown while logging the output of a failed process (non-zero exit, logger not at info). After detecting exitValue != 0, it calls outputLogger.accept(getLogger()) which invokes byteStreamToString(out) — a cast of OutputStream to ByteArrayOutputStream. If that cast or string conversion fails, the original failure is masked and rethrown as this GradleException.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/LoggedExec.java:184

            }
            if (getStandardInput().isPresent()) {
                execSpec.setStandardInput(new ByteArrayInputStream(getStandardInput().get().getBytes(StandardCharsets.UTF_8)));
            }
        });
        int exitValue = execResult.getExitValue();

        if (exitValue == 0 && getCaptureOutput().get()) {
            output = byteStreamToString(out);
        }
        if (getLogger().isInfoEnabled() == false) {
            if (exitValue != 0) {
                try {
                    if (getIndentingConsoleOutput().isPresent() == false) {
                        getLogger().error("Output for " + getExecutable().get() + ":");
                    }
                    outputLogger.accept(getLogger());
                } catch (Exception e) {
                    throw new GradleException("Failed to read exec output", e);
                }
                throw new GradleException(
                    String.format("Process '%s %s' finished with non-zero exit value %d", getExecutable().get(), getArgs().get(), exitValue)
                );
            }
        }

    }

    private String byteStreamToString(OutputStream out) {
        return ((ByteArrayOutputStream) out).toString(StandardCharsets.UTF_8);
    }

    public static ExecResult exec(ExecOperations execOperations, Action<ExecSpec> action) {
        return genericExec(execOperations::exec, action);
    }

    public static ExecResult javaexec(ExecOperations project, Action<JavaExecSpec> action) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the wrapped cause (GradleException.getCause()) for the real failure — typically a ClassCastException from byteStreamToString.
  2. If subclassing LoggedExec, ensure the `out` OutputStream passed to the logging path remains a ByteArrayOutputStream.
  3. Run with --info to take the early-return branch that bypasses this output-logging code entirely.
Defensive patterns

Strategy: try-catch

Try / catch

try { loggedExec.getActions(); } catch (GradleException e) { if (e.getMessage().contains("Failed to read exec output")) { log.error("Underlying cause:", e.getCause()); } throw e; }

Prevention

When it happens

Trigger: An executed process returns non-zero, logging level is above info (so the output-logging branch runs), and the output-logging lambda throws — typically because `out` is not a ByteArrayOutputStream (e.g., a custom OutputStream was injected) or a charset/IO issue occurs during toString.

Common situations: Subclassing LoggedExec and overriding the OutputStream handling; corruption of the captured stream; edge cases where the ByteArrayOutputStream cast in byteStreamToString fails. Rare in practice — usually indicates a subclassing bug.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/9f2f6fe6ffc9bdc2. Report an issue: GitHub.