{"record":{"id":"8d40d6fb7e8bd83c","repo":"conductor-oss/conductor","slug":"error-communicating-with-azure","errorCode":null,"errorMessage":"Error communicating with Azure","messagePattern":"Error communicating with Azure","errorType":"exception","errorClass":"NonTransientException","httpStatus":null,"severity":"error","filePath":"azureblob-storage/src/main/java/com/netflix/conductor/azureblob/storage/AzureBlobPayloadStorage.java","lineNumber":144,"sourceCode":"                    blobSASPermission.setReadPermission(true);\n                } else if (operation.equals(Operation.WRITE)) {\n                    blobSASPermission.setWritePermission(true);\n                    blobSASPermission.setCreatePermission(true);\n                }\n                BlobServiceSasSignatureValues blobServiceSasSignatureValues =\n                        new BlobServiceSasSignatureValues(\n                                OffsetDateTime.now(ZoneOffset.UTC).plusSeconds(expirationSec),\n                                blobSASPermission);\n                blobUrl =\n                        blobUrl + \"?\" + blockBlobClient.generateSas(blobServiceSasSignatureValues);\n            }\n\n            externalStorageLocation.setUri(blobUrl);\n            return externalStorageLocation;\n        } catch (BlobStorageException e) {\n            String msg = \"Error communicating with Azure\";\n            LOGGER.error(msg, e);\n            throw new NonTransientException(msg, e);\n        }\n    }\n\n    /**\n     * Uploads the payload to the given azure blob name. It is expected that the caller retrieves\n     * the blob name using {@link #getLocation(Operation, PayloadType, String)} before making this\n     * call.\n     *\n     * @param path the name of the blob 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            BlockBlobClient blockBlobClient =\n                    blobContainerClient.getBlobClient(path).getBlockBlobClient();\n            BlobHttpHeaders blobHttpHeaders = new BlobHttpHeaders().setContentType(CONTENT_TYPE);","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/azureblob-storage/src/main/java/com/netflix/conductor/azureblob/storage/AzureBlobPayloadStorage.java#L126-L162","documentation":"Thrown by AzureBlobPayloadStorage.getLocation when a BlobStorageException occurs while generating a pre-signed blob URL / SAS token for an upload or download location. BlobStorageException is raised by the Azure SDK for HTTP-level failures from the Storage service (auth errors, missing container, throttling). It is wrapped in a NonTransientException, meaning the caller is not expected to retry.","triggerScenarios":"Calling getLocation(Operation, PayloadType, String) when the blobContainerClient cannot reach or authenticate to Azure, the configured containerName does not exist, or generateSas fails because the client has no shared key / SAS to sign with.","commonSituations":"Using a connection string with a malformed/rotated account key. The container name configured does not exist in the storage account. Network egress blocked to *.blob.core.windows.net. SAS token expired between config and use.","solutions":["Check the logged BlobStorageException status code: 403 = bad/expired key or SAS; 404 = wrong container name; 503/429 = throttling.","Verify the storage account key or SAS token in the connection string is current and not expired.","Confirm the configured containerName exists in the storage account (create it if missing).","Ensure the runtime has network access to the Azure Storage endpoint from the Conductor host/container."],"exampleFix":"// before\nString msg = \"Error communicating with Azure\";\nLOGGER.error(msg, e);\nthrow new NonTransientException(msg, e);\n\n// after (surface the status code so callers can act on it)\nString msg = String.format(\"Error communicating with Azure (HTTP %d)\", e.getStatusCode());\nLOGGER.error(msg, e);\nthrow new NonTransientException(msg, e);","handlingStrategy":"try-catch","validationCode":"// Validate container name format and that endpoint/connectionString is set before getLocation\nif (isBlank(containerName)) throw new IllegalArgumentException(\"containerName required\");\nif (isBlank(connectionString) && isBlank(endpoint)) throw new IllegalArgumentException(\"endpoint or connectionString required\");","typeGuard":null,"tryCatchPattern":"try {\n    ExternalStorageLocation loc = storage.getLocation(op, type, name);\n} catch (NonTransientException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof BlobStorageException bse) {\n        log.error(\"Azure getLocation failed HTTP {}\", bse.getStatusCode());\n    }\n    throw e;\n}","preventionTips":["Pre-create the blob container before starting Conductor.","Rotate storage keys/SAS on a schedule and update config before expiry.","Monitor Azure Storage egress and throttle limits in the storage account diagnostics."],"tags":["azure","blob-storage","network","sas","external-payload"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}