jenkinsci/jenkins · error · IOException

Failed to install ${archive} to ${remote}

Error message

Failed to install ${archive} to ${remote}

What it means

Outer catch in FilePath.install(...) wrapping any IOException raised during the whole install operation (download, mkdirs, unpack, etag/timestamp write). It re-throws a fresh IOException with the caller's context (archive URL and remote path) and the original as cause. This is the top-level install failure surfaced to callers.

Source

Thrown at core/src/main/java/hudson/FilePath.java:1073

            InputStream in = archive.getProtocol().startsWith("http") ? ProxyConfiguration.getInputStream(archive) : con.getInputStream();
            CountingInputStream cis = new CountingInputStream(in);
            try {
                if (archive.toExternalForm().endsWith(".zip"))
                    unzipFrom(cis);
                else
                    untarFrom(cis, TarCompression.GZIP);
            } catch (IOException e) {
                throw new IOException(String.format("Failed to unpack %s (%d bytes read of total %d)",
                        archive, cis.getByteCount(), con.getContentLength()), e);
            }
            if (resultEtag != null && !equalETags(etag, resultEtag)) {
                /* Store the ETag value in the timestamp file for later use */
                timestamp.write(resultEtag, "UTF-8");
            }
            timestamp.touch(sourceTimestamp);
            return true;
        } catch (IOException e) {
            throw new IOException("Failed to install " + archive + " to " + remote, e);
        }
    }

    /* Return true if etag1 equals etag2 as defined by the etag specification
       https://httpwg.org/specs/rfc9110.html#field.etag
     */
    private boolean equalETags(String etag1, String etag2) {
        if (etag1 == null || etag2 == null) {
            return false;
        }
        if (etag1.equals(etag2)) {
            return true;
        }
        /* Weak tags are identified by leading characters "W/" as a marker */
        /* Weak tag marker must not be considered in tag comparison.
           This implements the weak comparison in the specification at
           https://httpwg.org/specs/rfc9110.html#field.etag */
        String opaqueTag1 = etag1.startsWith("W/") ? etag1.substring(2) : etag1;

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Read the nested cause to find the specific failure (unpack, mkdirs, network).
  2. Verify the remote path exists and is writable, and the agent channel is up.
  3. Confirm the archive URL is reachable and returns the expected content.
  4. Fix the root cause identified in the cause chain, then retry install.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
    fp.install(archive, listener);
} catch (IOException e) {
    // 'Failed to install' — inspect e.getCause() for the specific failure
    LOGGER.log(Level.SEVERE, "install failed", e.getCause());
}

Prevention

When it happens

Trigger: Any IOException from connect/getInputStream, mkdirs, unzipFrom/untarFrom, the inner 'Failed to unpack', or timestamp.touch; the agent-side Unpack retry already failed and fell through to controller-side unpack which then failed.

Common situations: Target directory not writable; remote agent path invalid or disconnected; archive URL returns 4xx/5xx; nested cause is one of the more specific unpack/mkdirs errors.

Related errors


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