apache/beam · error · NoSuchElementException
Failed to list first page of FHIR resources from
Error message
Failed to list first page of FHIR resources from %s: %s
What it means
The FHIR store 'has any resources' check in HttpHealthcareApiClient throws NoSuchElementException when the initial FHIR search request throws IOException, converting an I/O/API failure into an empty-result signal for the hasNext() contract. The real cause (store not found, no permission, malformed request) is appended in the message.
Solutions
- Verify the fhirStore full resource path (projects/{p}/locations/{l}/datasets/{d}/fhirStores/{s})
- Grant roles/healthcare.fhirStoreViewer to the caller's service account
- Check the embedded IOException message for the actual HTTP cause
- Confirm the FHIR store exists via `gcloud healthcare fhir-stores describe` and retry on transient failures
Example fix
// before
throw new NoSuchElementException(String.format("Failed to list first page of FHIR resources from %s: %s", fhirStore, e.getMessage()));
// after
// validate store accessibility before iterating
try {
boolean hasResources = client.hasFhirResources(fhirStore);
} catch (NoSuchElementException e) {
throw new IOException("Cannot access FHIR store " + fhirStore + ": " + e.getMessage(), e);
} Defensive patterns
Strategy: try-catch
Validate before calling
java
if (!fhirStore.matches("projects/[^/]+/locations/[^/]+/datasets/[^/]+/fhirStores/[^/]+")) {
throw new IllegalArgumentException("Malformed fhirStore path: " + fhirStore);
} Try / catch
java
try {
hasResources = checkFirstPage(fhirStore);
} catch (NoSuchElementException e) {
throw new IOException("FHIR store unreachable: " + e.getMessage(), e);
} Prevention
- Verify the FHIR store exists and IAM read access before running the pipeline
- Catch NoSuchElementException and rethrow with the embedded cause for diagnosability
- Retry transient failures with backoff
- Confirm store region/location matches the client's endpoint
When it happens
Trigger: Calling the method that checks for the first page of FHIR resources (used by FhirIO source hasNext) when the FHIR stores.search/.list REST request fails: wrong fhirStore path, missing healthcare.fhirStoreViewer IAM role, network outage, or API error response.
Common situations: Misspelled datasets/{d}/fhirStores/{s} path; service account without FHIR read permissions; transient 5xx during a Beam FHIR import/export pipeline; FHIR store not yet created.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Error listing FHIR resources from
- Error listing HL7v2 Messages from
- 2xx codes should not be exceptions. Got status code
- Could not find earliest send time. The filter
- Could not find latest send time. The filter
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/aadf3601d3ca934f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/HttpHealthcareApiClient.java:976
public static FhirResourcePagesIterator ofPatientEverything(
HealthcareApiClient client, String resourceName, @Nullable Map<String, Object> parameters) {
return new FhirResourcePagesIterator(
FhirMethod.PATIENT_EVERYTHING, client, "", "", resourceName, parameters);
}
@Override
public boolean hasNext() throws NoSuchElementException {
if (!isFirstRequest) {
return this.pageToken != null && !this.pageToken.isEmpty();
}
try {
HttpBody response = executeFhirRequest();
JsonObject jsonResponse =
JsonParser.parseString(mapper.writeValueAsString(response)).getAsJsonObject();
JsonArray resources = jsonResponse.getAsJsonArray("entry");
return resources != null && resources.size() != 0;
} catch (IOException e) {
throw new NoSuchElementException(
String.format(
"Failed to list first page of FHIR resources from %s: %s",
fhirStore, e.getMessage()));
}
}
@Override
public JsonArray next() throws NoSuchElementException {
try {
HttpBody response = executeFhirRequest();
this.isFirstRequest = false;
JsonObject jsonResponse =
JsonParser.parseString(mapper.writeValueAsString(response)).getAsJsonObject();
JsonArray links = jsonResponse.getAsJsonArray("link");
this.pageToken = parsePageToken(links);
JsonArray resources = jsonResponse.getAsJsonArray("entry");
return resources;
} catch (IOException e) {View on GitHub (pinned to 12126d8942)