conductor-oss/conductor · error · TransientException

Error downloading from S3 - path:%s

Error message

Error downloading from S3 - path:%s

What it means

Thrown as TransientException (wrapping SdkException) by S3PayloadStorage.download when s3Client.getObject fails. As with upload, SdkException-class errors are treated as retriable. Note: a 'key not found' (NoSuchKey/S3Exception 404) is also an SdkException subclass and would surface here, so callers must distinguish missing objects from transient failures via the chained cause.

Source

Thrown at awss3-storage/src/main/java/com/netflix/conductor/s3/storage/S3PayloadStorage.java:188

    /**
     * Downloads the payload stored in the s3 object.
     *
     * @param path the S3 key of the object
     * @return an input stream containing the contents of the object Caller is expected to close the
     *     input stream.
     */
    @Override
    public InputStream download(String path) {
        try {
            GetObjectRequest request =
                    GetObjectRequest.builder().bucket(bucketName).key(path).build();

            return s3Client.getObject(request);
        } catch (SdkException e) {
            String msg = String.format("Error downloading from S3 - path:%s", path);
            LOGGER.error(msg, e);
            throw new TransientException(msg, e);
        }
    }

    private String getObjectKey(PayloadType payloadType) {
        StringBuilder stringBuilder = new StringBuilder();
        switch (payloadType) {
            case WORKFLOW_INPUT:
                stringBuilder.append("workflow/input/");
                break;
            case WORKFLOW_OUTPUT:
                stringBuilder.append("workflow/output/");
                break;
            case TASK_INPUT:
                stringBuilder.append("task/input/");
                break;
            case TASK_OUTPUT:
                stringBuilder.append("task/output/");
                break;

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inspect the chained SdkException: a NoSuchKey/404 means the object is genuinely absent (do not retry); other SdkExceptions are retriable.
  2. Retry with backoff for non-404 SdkExceptions.
  3. Grant s3:GetObject and verify the object key exists (it should match the path returned by getLocation at upload time).
  4. Check bucket lifecycle rules are not expiring payloads prematurely.

Example fix

// before
InputStream in = storage.download(path); // may throw TransientException
// after
try {
    InputStream in = storage.download(path);
} catch (TransientException te) {
    if (te.getCause() instanceof NoSuchKey) {
        // object genuinely missing — handle absence, do not retry
    } else {
        RetryUtils.retryOn(TransientException.class, 5, Duration.ofMillis(300),
            () -> storage.download(path));
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

import org.apache.commons.lang3.StringUtils;
if (StringUtils.isBlank(path)) throw new IllegalArgumentException("download path is required");
// Best-effort existence check (note: adds a HEAD call)
// s3Client.headObject(h -> h.bucket(bucketName).key(path));

Try / catch

import software.amazon.awssdk.services.s3.model.NoSuchKey;
import software.amazon.awssdk.services.s3.model.S3Exception;
try {
    return storage.download(path);
} catch (TransientException te) {
    Throwable c = te.getCause();
    if (c instanceof S3Exception s3 && s3.statusCode() == 404) {
        // object genuinely missing — handle absence, do NOT retry
        throw new IllegalStateException("S3 object not found: " + path, te);
    }
    // otherwise retriable — bounded backoff retry
    throw te;
}

Prevention

When it happens

Trigger: Network error, throttling, credential expiry, IAM denial on s3:GetObject, or the requested object key not existing in the bucket. Caught in download's SdkException handler.

Common situations: Attempting to download a payload whose upload failed or was pruned; missing s3:GetObject permission; transient network; lifecycle policy deleted the object.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/0998d24f8566091a. Report an issue: GitHub.