apache/beam · error
read resource request returned error on input
Error message
read resource request returned error on input: [%v]
What it means
readResourceFn.ProcessElement calls client.readResource(resourcePath) to GET a single FHIR resource. If the HTTP request fails, the error is wrapped with this message including the input resource path and emitted to the dead-letter channel; the element is not retried automatically by fhirio.
Solutions
- Verify each resourcePath is a valid full FHIR resource path and the resource exists (curl the URL directly)
- Check worker network egress to healthcare.googleapis.com (VPC settings, firewall)
- Validate credentials/scopes (cloud-healthcare scope, ADC configured on workers)
- Implement a retry/dead-letter replay: read emitDeadLetter output and reprocess failed paths with backoff
- Confirm the FHIR store was not deleted/moved mid-pipeline
Example fix
// before
emitDeadLetter(errors.Wrapf(err, "read resource request returned error on input: [%v]", resourcePath).Error())
// after
if isTransient(err) {
return retryRead(resourcePath, 3) // exponential backoff
}
emitDeadLetter(errors.Wrapf(err, "read resource request returned error on input: [%v]", resourcePath).Error()) Defensive patterns
Strategy: retry
Validate before calling
resourcePath := "projects/p/locations/l/datasets/d/fhirStores/s/fhir/Patient/123"
parts := strings.Split(resourcePath, "/")
if len(parts) != 10 || parts[8] != "fhir" { return fmt.Errorf("bad resource path: %s", resourcePath) } Try / catch
// wrap reads with backoff retry for transient errors
for attempt := 0; attempt < 3; attempt++ {
resp, err := client.readResource(path)
if err == nil { return resp }
if !isTransient(err) { break }
time.Sleep(backoff(attempt))
} Prevention
- Sanity-check resource IDs in upstream PCollections
- Verify store and resources exist before the pipeline runs
- Ensure workers have healthcare API egress and credentials
- Always route failures to the dead-letter channel and monitor it
When it happens
Trigger: fn.client.readResource(resourcePath) returns a non-nil error: DNS/network failure, invalid resourcePath (malformed projects/.../fhirStores/<s>/fhir/<type>/<id> path), timeouts, or a failed access token refresh inside the client.
Common situations: Resource ID typos in the source PCollection; store deleted or renamed between pipeline stages; no network from Dataflow workers; expired/insufficient credentials for the Healthcare API.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- execute bundle request returned error
- failed to connect to
- Artifact not found at
- chunk send failed
- could not create data operations client
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6497fc0c241a75bc.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/io/fhirio/read.go:52
type readResourceFn struct {
fnCommonVariables
}
func (fn readResourceFn) String() string {
return "readResourceFn"
}
func (fn *readResourceFn) Setup() {
fn.fnCommonVariables.setup(fn.String())
}
func (fn *readResourceFn) ProcessElement(ctx context.Context, resourcePath []byte, emitResource, emitDeadLetter func(string)) {
response, err := executeAndRecordLatency(ctx, &fn.latencyMs, func() (*http.Response, error) {
return fn.client.readResource(resourcePath)
})
if err != nil {
fn.resourcesErrorCount.Inc(ctx, 1)
emitDeadLetter(errors.Wrapf(err, "read resource request returned error on input: [%v]", resourcePath).Error())
return
}
body, err := extractBodyFrom(response)
if err != nil {
fn.resourcesErrorCount.Inc(ctx, 1)
emitDeadLetter(errors.Wrapf(err, "could not extract body from read resource [%v] response", resourcePath).Error())
return
}
fn.resourcesSuccessCount.Inc(ctx, 1)
emitResource(body)
}
// Read fetches resources from Google Cloud Healthcare FHIR stores based on the
// resource path. It consumes a PCollection<string> of notifications from the
// FHIR store of resource paths, and fetches the actual resource object on the
// path in the notification. It outputs two PCollection<string>. The firstView on GitHub (pinned to 12126d8942)