{"record":{"id":"56eb904bffebe947","repo":"conductor-oss/conductor","slug":"error-generating-presigned-url","errorCode":null,"errorMessage":"Error generating presigned URL","messagePattern":"Error generating presigned URL","errorType":"exception","errorClass":"NonTransientException","httpStatus":null,"severity":"error","filePath":"awss3-storage/src/main/java/com/netflix/conductor/s3/storage/S3PayloadStorage.java","lineNumber":137,"sourceCode":"                                .getObjectRequest(getObjectRequest)\n                                .build();\n\n                presignedUrl = s3Presigner.presignGetObject(presignRequest).url().toString();\n            }\n\n            externalStorageLocation.setUri(presignedUrl);\n            return externalStorageLocation;\n        } catch (SdkException e) {\n            String msg =\n                    String.format(\n                            \"Error communicating with S3 - operation:%s, payloadType: %s, path: %s\",\n                            operation, payloadType, path);\n            LOGGER.error(msg, e);\n            throw new TransientException(msg, e);\n        } catch (Exception e) {\n            String msg = \"Error generating presigned URL\";\n            LOGGER.error(msg, e);\n            throw new NonTransientException(msg, e);\n        }\n    }\n\n    /**\n     * Uploads the payload to the given s3 object key. It is expected that the caller retrieves the\n     * object key using {@link #getLocation(Operation, PayloadType, String)} before making this\n     * call.\n     *\n     * @param path the s3 key of the object to be uploaded\n     * @param payload an {@link InputStream} containing the json payload which is to be uploaded\n     * @param payloadSize the size of the json payload in bytes\n     */\n    @Override\n    public void upload(String path, InputStream payload, long payloadSize) {\n        try {\n            PutObjectRequest request =\n                    PutObjectRequest.builder()\n                            .bucket(bucketName)","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/awss3-storage/src/main/java/com/netflix/conductor/s3/storage/S3PayloadStorage.java#L119-L155","documentation":"Thrown as NonTransientException by getLocation's generic catch (Exception) when presigned-URL generation fails with something that is NOT an SdkException. Because it is not an SDK/network error, conductor treats it as a configuration/programming problem that retrying will not fix. The message is generic, so the chained exception 'e' holds the real cause.","triggerScenarios":"NullPointerException or IllegalStateException during request building (e.g. null bucket name, null objectKey), an invalid signatureDuration, or a misconfigured S3Presigner. Falls through the SdkException catch into the generic Exception catch.","commonSituations":"bucketName property unset (null) so the builder throws; signatureDuration misconfigured; an empty path producing an invalid key; S3Presigner not initialized correctly.","solutions":["Read the chained exception 'e' — it names the real cause (often NPE on bucket/key).","Ensure conductor.payload-storage.s3.bucket (or equivalent) is set to a non-empty value.","Validate the path argument and signatureDuration before calling getLocation.","Do not retry — NonTransientException indicates retrying will keep failing until config changes."],"exampleFix":"// before — bucket name unset, NPE thrown, wrapped as NonTransientException\n// after\nconductor.payload-storage.s3.bucket=my-payload-bucket\nconductor.payload-storage.s3.region=us-east-1","handlingStrategy":"validation","validationCode":"import org.apache.commons.lang3.StringUtils;\nif (StringUtils.isBlank(bucketName)) {\n    throw new IllegalStateException(\"conductor.payload-storage.s3.bucket is not configured\");\n}\nif (StringUtils.isBlank(path)) {\n    throw new IllegalArgumentException(\"path is required for getLocation\");\n}\nif (signatureDuration == null || signatureDuration.isNegative()) {\n    throw new IllegalStateException(\"signatureDuration is invalid: \" + signatureDuration);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return storage.getLocation(operation, payloadType, path);\n} catch (NonTransientException e) {\n    // Read chained cause (often NPE on bucket/key) — fix config, do not retry\n    log.error(\"Non-transient S3 presign failure: {}\", e.getCause(), e);\n    throw e;\n}","preventionTips":["Always set the S3 bucket and region properties.","Validate path and signatureDuration before calling getLocation.","Do not retry NonTransientException — fix the underlying config."],"tags":["s3","aws","configuration","storage"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}