From 3ddf4b88e2e9c28077241996d0900feea9500db5 Mon Sep 17 00:00:00 2001 From: vcolin7 Date: Fri, 23 Jan 2026 19:59:12 -0800 Subject: [PATCH 1/2] Added null checks for HttpResponseException.getResponse() --- .../KeyVaultAdministrationUtil.java | 2 +- .../certificates/CertificateAsyncClient.java | 20 +++++++++---------- .../certificates/CertificateClient.java | 4 ++-- .../keyvault/keys/KeyAsyncClient.java | 10 +++++----- .../security/keyvault/keys/KeyClient.java | 4 ++-- .../CryptographyClientImpl.java | 2 +- .../implementation/CryptographyUtils.java | 8 +++++++- .../keyvault/secrets/SecretAsyncClient.java | 10 +++++----- .../keyvault/secrets/SecretClient.java | 4 ++-- 9 files changed, 35 insertions(+), 29 deletions(-) diff --git a/sdk/keyvault/azure-security-keyvault-administration/src/main/java/com/azure/security/keyvault/administration/KeyVaultAdministrationUtil.java b/sdk/keyvault/azure-security-keyvault-administration/src/main/java/com/azure/security/keyvault/administration/KeyVaultAdministrationUtil.java index 3677431898f1..ffb3c9e8b3e3 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/src/main/java/com/azure/security/keyvault/administration/KeyVaultAdministrationUtil.java +++ b/sdk/keyvault/azure-security-keyvault-administration/src/main/java/com/azure/security/keyvault/administration/KeyVaultAdministrationUtil.java @@ -96,7 +96,7 @@ static Response swallowExceptionForStatu HttpResponse httpResponse = httpResponseException.getResponse(); - if (httpResponse.getStatusCode() == statusCode) { + if (httpResponse != null && httpResponse.getStatusCode() == statusCode) { return new SimpleResponse<>(httpResponse.getRequest(), httpResponse.getStatusCode(), httpResponse.getHeaders(), null); } diff --git a/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateAsyncClient.java b/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateAsyncClient.java index 5d25abf8370f..da2d5e0dc7f9 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateAsyncClient.java +++ b/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateAsyncClient.java @@ -410,7 +410,7 @@ private Mono createCertificateActivation(String certificat * @return A {@link ResourceModifiedException} created from the {@link HttpResponseException}. */ static HttpResponseException mapCreateCertificateException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 400 + return e.getResponse() != null && e.getResponse().getStatusCode() == 400 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -430,7 +430,7 @@ private Mono> certificatePollOperation(String * @return A {@link ResourceModifiedException} created from the {@link HttpResponseException}. */ static HttpResponseException mapGetCertificateOperationException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 400 + return e.getResponse() != null && e.getResponse().getStatusCode() == 400 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -472,7 +472,7 @@ private Mono certificateCancellationOperation(String certi } static HttpResponseException mapUpdateCertificateOperationException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 400 + return e.getResponse() != null && e.getResponse().getStatusCode() == 400 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -486,7 +486,7 @@ private Mono fetchCertificateOperation(String cer } static HttpResponseException mapGetCertificateException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 403 + return e.getResponse() != null && e.getResponse().getStatusCode() == 403 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -813,7 +813,7 @@ private Mono deleteCertificateActivation(String certificateN } static HttpResponseException mapDeleteCertificateException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 404 + return e.getResponse() != null && e.getResponse().getStatusCode() == 404 ? new ResourceNotFoundException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -825,7 +825,7 @@ private Mono> deleteCertificatePollOperation(St .map(binaryData -> new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createDeletedCertificate(binaryData.toObject(DeletedCertificateBundle.class)))) .onErrorResume(HttpResponseException.class, e -> { - if (e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue())); } else { @@ -1021,7 +1021,7 @@ private Mono> recoverDeletedCertific .map(binaryData -> new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createCertificateWithPolicy(binaryData.toObject(CertificateBundle.class)))) .onErrorResume(HttpResponseException.class, e -> { - if (e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue())); } else { @@ -1167,7 +1167,7 @@ public Mono> restoreCertificateBackupWit } static HttpResponseException mapRestoreCertificateException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 400 + return e.getResponse() != null && e.getResponse().getStatusCode() == 400 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -1523,7 +1523,7 @@ public Mono> getCertificatePolicyWithResponse(String } static HttpResponseException mapGetCertificatePolicyException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 403 + return e.getResponse() != null && e.getResponse().getStatusCode() == 403 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -2123,7 +2123,7 @@ public Mono> deleteCertificateOperationWithRespon } static HttpResponseException mapDeleteCertificateOperationException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 400 + return e.getResponse() != null && e.getResponse().getStatusCode() == 400 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } diff --git a/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateClient.java b/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateClient.java index ec8a115ee89e..00e25b18005d 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateClient.java +++ b/sdk/keyvault/azure-security-keyvault-certificates/src/main/java/com/azure/security/keyvault/certificates/CertificateClient.java @@ -708,7 +708,7 @@ private PollResponse deleteCertificatePollOperation(String c .getValue() .toObject(DeletedCertificateBundle.class))); } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue()); } else { @@ -896,7 +896,7 @@ private PollResponse recoverDeletedCertificatePol .getValue() .toObject(CertificateBundle.class))); } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue()); } else { diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyAsyncClient.java b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyAsyncClient.java index 7f345f002d59..ace36d9f98fd 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyAsyncClient.java +++ b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyAsyncClient.java @@ -365,7 +365,7 @@ public Mono> createKeyWithResponse(CreateKeyOptions create } static HttpResponseException mapCreateKeyException(HttpResponseException e) { - return (e.getResponse().getStatusCode() == 400) + return (e.getResponse() != null && e.getResponse().getStatusCode() == 400) ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -983,7 +983,7 @@ public Mono> getKeyWithResponse(String name, String versio * @return The {@link HttpResponseException} that maps from the {@link HttpResponseException}. */ static HttpResponseException mapGetKeyException(HttpResponseException e) { - return e.getResponse().getStatusCode() == 403 + return e.getResponse() != null && e.getResponse().getStatusCode() == 403 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -1177,7 +1177,7 @@ private Function, Mono>> del .map(response -> new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createDeletedKey(response.getValue().toObject(DeletedKeyBundle.class)))) .onErrorResume(HttpResponseException.class, e -> { - if (e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue())); } else { @@ -1364,7 +1364,7 @@ private Function, Mono> recoverActivati .map(response -> new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createKeyVaultKey(response.getValue().toObject(KeyBundle.class)))) .onErrorResume(HttpResponseException.class, e -> { - if (e.getResponse().getStatusCode() == 404) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == 404) { return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue())); } else { @@ -1548,7 +1548,7 @@ public Mono> restoreKeyBackupWithResponse(byte[] backup) { } static HttpResponseException mapRestoreKeyException(HttpResponseException e) { - return (e.getResponse().getStatusCode() == 400) + return (e.getResponse() != null && e.getResponse().getStatusCode() == 400) ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyClient.java b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyClient.java index 940a13895228..464245b8af71 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyClient.java +++ b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/KeyClient.java @@ -1104,7 +1104,7 @@ private Function, PollResponse> deletePol .getValue() .toObject(DeletedKeyBundle.class))); } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue()); } else { @@ -1285,7 +1285,7 @@ private Function, PollResponse> recover return new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createKeyVaultKey( implClient.getKeyWithResponse(keyName, null, EMPTY_OPTIONS).getValue().toObject(KeyBundle.class))); } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == 404) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == 404) { return new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue()); } else { diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java index e2a2e08df12b..d5d633cb079c 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java +++ b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyClientImpl.java @@ -93,7 +93,7 @@ public String getKeyCollection() { public Mono> getKeyAsync() { return keyClient.getKeyWithResponseAsync(keyName, keyVersion, EMPTY_OPTIONS) .onErrorMap(HttpResponseException.class, - e -> e.getResponse().getStatusCode() == 403 + e -> e.getResponse() != null && e.getResponse().getStatusCode() == 403 ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e) .map(response -> new SimpleResponse<>(response, diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java index 47e9d69775d1..77df0a11c34b 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java +++ b/sdk/keyvault/azure-security-keyvault-keys/src/main/java/com/azure/security/keyvault/keys/cryptography/implementation/CryptographyUtils.java @@ -152,7 +152,13 @@ public static void verifyKeyPermissions(JsonWebKey jsonWebKey, KeyOperation keyO public static boolean isThrowableRetryable(Throwable e) { if (e instanceof HttpResponseException) { - int statusCode = ((HttpResponseException) e).getResponse().getStatusCode(); + HttpResponseException httpResponseException = (HttpResponseException) e; + + if (httpResponseException.getResponse() == null) { + return false; + } + + int statusCode = httpResponseException.getResponse().getStatusCode(); // Not a retriable error code. return statusCode != 501 diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java index e295096f9202..ec81887f62c2 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java @@ -316,7 +316,7 @@ public Mono> setSecretWithResponse(KeyVaultSecret secre // For some reason, the service does not return a 409 when a secret with the same name exists. Instead, it returns // a 400. static HttpResponseException mapSetSecretException(HttpResponseException e) { - return (e.getResponse().getStatusCode() == 400) + return (e.getResponse() != null && e.getResponse().getStatusCode() == 400) ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } @@ -443,7 +443,7 @@ public Mono> getSecretWithResponse(String name, String // For some reason, the service does not return a 409 when a secret with the same name exists. Instead, it returns // a 403. static HttpResponseException mapGetSecretException(HttpResponseException e) { - if (e.getResponse().getStatusCode() == 403) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == 403) { return new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()); } else { return e; @@ -597,7 +597,7 @@ private Function, Mono> deleteActiv .map(response -> new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createDeletedSecret(response.getValue().toObject(DeletedSecretBundle.class)))) .onErrorResume(HttpResponseException.class, exception -> { - if (exception.getResponse().getStatusCode() == 404) { + if (exception.getResponse() != null && exception.getResponse().getStatusCode() == 404) { return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue())); } else { @@ -790,7 +790,7 @@ private Function, Mono> recoverAc .map(response -> new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createKeyVaultSecret(response.getValue().toObject(SecretBundle.class)))) .onErrorResume(HttpResponseException.class, exception -> { - if (exception.getResponse().getStatusCode() == 404) { + if (exception.getResponse() != null && exception.getResponse().getStatusCode() == 404) { return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue())); } else { @@ -944,7 +944,7 @@ public Mono> restoreSecretBackupWithResponse(byte[] bac // For some reason, the service does not return a 409 but a 400 in this case. static HttpResponseException mapRestoreSecretException(HttpResponseException e) { - return (e.getResponse().getStatusCode() == 400) + return (e.getResponse() != null && e.getResponse().getStatusCode() == 400) ? new ResourceModifiedException(e.getMessage(), e.getResponse(), e.getValue()) : e; } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java index c735d1864ff4..80598d9a596c 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java @@ -548,7 +548,7 @@ private Function, PollResponse> del .getValue() .toObject(DeletedSecretBundle.class))); } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == 404) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == 404) { return new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue()); } else { @@ -720,7 +720,7 @@ private Function, PollResponse> r return new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, createKeyVaultSecret( implClient.getSecretWithResponse(name, "", EMPTY_OPTIONS).getValue().toObject(SecretBundle.class))); } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == 404) { + if (e.getResponse() != null && e.getResponse().getStatusCode() == 404) { return new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, pollingContext.getLatestResponse().getValue()); } else { From afea0f147dd9e193bb36c3ad638b66c0c30ccd27 Mon Sep 17 00:00:00 2001 From: vcolin7 Date: Sat, 24 Jan 2026 09:44:36 -0800 Subject: [PATCH 2/2] Updated CHANGELOGs --- .../azure-security-keyvault-administration/CHANGELOG.md | 2 ++ sdk/keyvault/azure-security-keyvault-certificates/CHANGELOG.md | 2 ++ sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md | 2 ++ sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md | 2 ++ 4 files changed, 8 insertions(+) diff --git a/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md index 07ad5ab11565..d2d8330e4d2e 100644 --- a/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-administration/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed an issue where certain `HttpResponseException.getResponse()` calls could cause a `NullPointerException`. ([#47801](https://github.com/Azure/azure-sdk-for-java/issues/47801)) + ### Other Changes ## 4.7.4 (2025-10-27) diff --git a/sdk/keyvault/azure-security-keyvault-certificates/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-certificates/CHANGELOG.md index d93f58cd985e..54bb483e9721 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-certificates/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed an issue where certain `HttpResponseException.getResponse()` calls could cause a `NullPointerException`. ([#47801](https://github.com/Azure/azure-sdk-for-java/issues/47801)) + ### Other Changes ## 4.8.4 (2025-10-27) diff --git a/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md index 023656fc4244..69c58f77e782 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed an issue where certain `HttpResponseException.getResponse()` calls could cause a `NullPointerException`. ([#47801](https://github.com/Azure/azure-sdk-for-java/issues/47801)) + ### Other Changes ## 4.10.4 (2025-10-27) diff --git a/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md index 9dd1493fe3e9..8f0f950a5016 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed an issue where certain `HttpResponseException.getResponse()` calls could cause a `NullPointerException`. ([#47801](https://github.com/Azure/azure-sdk-for-java/issues/47801)) + ### Other Changes ## 4.10.4 (2025-10-27)