apache/beam · error · IOException

Couldn't find message: %s.

Error message

Couldn't find message: %s.

What it means

HttpHealthcareApiClient.getHL7v2Message performs a direct GET of an HL7v2 message by its resource name. If the HTTP client returns null (no message model deserialized), the method throws IOException with the message name, translating a null API result into the checked IO error the interface declares.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/HttpHealthcareApiClient.java:424

      return baseRequest.execute();
    } else {
      return baseRequest.setOrderBy(orderBy).execute();
    }
  }

  /**
   * Gets HL7v2 message.
   *
   * @param msgName the msg name
   * @return the message
   * @throws IOException the io exception
   */
  @Override
  public Message getHL7v2Message(String msgName) throws IOException {
    Message msg =
        client.projects().locations().datasets().hl7V2Stores().messages().get(msgName).execute();
    if (msg == null) {
      throw new IOException(String.format("Couldn't find message: %s.", msgName));
    }
    return msg;
  }

  @Override
  public Empty deleteHL7v2Message(String msgName) throws IOException {
    return client
        .projects()
        .locations()
        .datasets()
        .hl7V2Stores()
        .messages()
        .delete(msgName)
        .execute();
  }

  /**
   * Gets HL7v2 store.

View on GitHub (pinned to 12126d8942)

Solutions

  1. Verify the full message resource name (projects/*/locations/*/datasets/*/hl7V2Stores/*/messages/*) is correct and the message still exists.
  2. Retry briefly and check store configuration — deleted messages cannot be recovered; rely on dead-letter handling for missing messages.
  3. Catch the IOException in the caller and skip/dead-letter the message instead of failing the pipeline.
  4. Confirm service-account permissions on the store (view access).

Example fix

// before
Message m = client.getHL7v2Message(name); // IOException if null

// after
Message m;
try {
  m = client.getHL7v2Message(name);
} catch (IOException e) {
  LOG.warn("Message {} not found; skipping", name);
  return null;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (msgName == null || !msgName.startsWith("projects/")) {
  throw new IllegalArgumentException("Malformed HL7v2 message name: " + msgName);
}

Try / catch

try {
  Message msg = client.getHL7v2Message(msgName);
} catch (IOException e) {
  LOG.warn("Message {} not found: {}", msgName, e.getMessage());
  // skip or dead-letter
}

Prevention

When it happens

Trigger: getHL7v2Message(msgName) is called and the underlying Healthcare API client execute() returns null — the message resource name does not resolve (deleted message, malformed msgName, wrong store), or the response body was empty.

Common situations: Consuming notification payloads whose messages have already been ACKed and deleted; building msgName strings by hand with wrong project/dataset/store segments; permissions issues surfacing as empty rather than error responses.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/ae9a80e740c85c84. Report an issue: GitHub.