HAPI FhirValidator unable to find resource

41 views
Skip to first unread message

Matthew Weiler

unread,
Oct 20, 2025, 10:37:48 AMOct 20
to HAPI FHIR
We've been using the standard FHIR validator to validated incoming FHIR request messages, but under heavy load, it's not performant.

We have been trying to integrate the HAPI FHIR validator, but at this point it fails to validate our requests.

It looks like a missing dependency, but I'm not sure what is needed :(

Maven Dependencies

<dependency>

<groupId>ca.uhn.hapi.fhir</groupId>

<artifactId>hapi-fhir-structures-dstu3</artifactId>

<version>6.10.5</version>

</dependency>

<dependency>

<groupId>ca.uhn.hapi.fhir</groupId>

<artifactId>hapi-fhir-structures-r4</artifactId>

<version>6.10.5</version>

</dependency>

<dependency>

<groupId>ca.uhn.hapi.fhir</groupId>

<artifactId>hapi-fhir-validation</artifactId>

<version>6.10.5</version>

</dependency>

<dependency>

<groupId>ca.uhn.hapi.fhir</groupId>

<artifactId>hapi-fhir-validation-resources-r4</artifactId>

<version>6.10.5</version>

</dependency>


Sample Code
I've modified the below code to put the creation of the FhirValidator inline rather than in a separate method.

private boolean validateFhirRequest(

final String fhirRequestMessage

)

throws Exception

{

// Create a FhirContext for the desired FHIR version (e.g., DSTU3, R4).

final FhirContext fhirContext = FhirContext.forDstu3();

// Create NpmPackageValidationSupport to load your TGZ package.

final NpmPackageValidationSupport npmPackageSupport = new NpmPackageValidationSupport(fhirContext);

try

{

// Load the TGZ package from the classpath.

// Ensure the TGZ file is accessible on the classpath (e.g., in resources folder).

npmPackageSupport.loadPackageFromClasspath(this.eClaimsTgzFileClassPath);

}

catch (IOException ioe)

{

throw new Exception("Failed to load TGZ file.");

}

// Create a ValidationSupportChain

// Include DefaultProfileValidationSupport for core FHIR definitions and SnapshotGeneratingValidationSupport

// for generating snapshots if your IG profiles require them.

final ValidationSupportChain validationSupportChain = new ValidationSupportChain(

npmPackageSupport,

new DefaultProfileValidationSupport(fhirContext),

new CommonCodeSystemsTerminologyService(fhirContext),

new InMemoryTerminologyServerValidationSupport(fhirContext),

new SnapshotGeneratingValidationSupport(fhirContext)

);

// Create the FhirValidator from the current context.

final FhirValidator fhirValidator = fhirContext.newValidator();

fhirValidator.setConcurrentBundleValidation(false);

fhirValidator.setValidateAgainstStandardSchema(true);

final FhirInstanceValidator fhirInstanceValidator = new FhirInstanceValidator(validationSupportChain);

fhirInstanceValidator.setAnyExtensionsAllowed(true);

// fhirInstanceValidator.setAssumeValidRestReferences(true);

// fhirInstanceValidator.setCustomExtensionDomains("");

fhirInstanceValidator.setErrorForUnknownProfiles(false);

// fhirInstanceValidator.setNoBindingMsgSuppressed(true);

// fhirInstanceValidator.setNoExtensibleWarnings(true);

fhirInstanceValidator.setNoTerminologyChecks(true);

// fhirInstanceValidator.setValidatorPolicyAdvisor(null);

// fhirInstanceValidator.setValidatorResourceFetcher(null);

// Register the validation-support-chain.

fhirValidator.registerValidatorModule(fhirInstanceValidator);

try

{

final ValidationResult validationResult = fhirValidator.validateWithResult(fhirRequestMessage);

if (validationResult.isSuccessful())

{

return true;

}

System.out.println("\nRaw resource string is invalid. Validation messages:");

boolean errorsFound = false;

for (SingleValidationMessage next : validationResult.getMessages())

{

if (

(next.getSeverity() != ResultSeverityEnum.ERROR)

&&

(next.getSeverity() != ResultSeverityEnum.FATAL)

)

{

continue;

}

errorsFound = true;

System.out.println("\t - " + next.getMessage());

}

return !errorsFound;

}

catch (final Throwable thrown)

{

throw new Exception(thrown);

}

}


Error Thrown 

HAPI-1758: Unable to find classpath resource: /org/hl7/fhir/dstu3/model/schema/fhir-single.xsd

James Agnew

unread,
Oct 20, 2025, 10:47:26 AMOct 20
to Matthew Weiler, HAPI FHIR
Hi Matthew,

Your code does look right to me, at least by eyeballing it. A couple of comments:

- You're using a fairly old version of HAPI FHIR, the validator has had all kinds of improvements in terms of both performance and correctness in the last few years so it's definitely worth looking at whether you can use a more current version.
- I'm guessing from the code that you're validating DSTU3 content, so you'll want to have the "hapi-fhir-validation-resources-dstu3" dependency added to your POM
- You should consider disabling "setValidateAgainstStandardSchema". The FhirInstanceValidator these days catches all of the same issues using StructureDefinition validation that the schema/schematron validator would catch, and the StructureDefinition version produces much more helpful error messages. Definitely nothing wrong with using the Schema/Schematron validation if you have reasons to need it, but it's definitely worth thinking about.

Cheers,
James

--
You received this message because you are subscribed to the Google Groups "HAPI FHIR" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/hapi-fhir/4ddc6f71-1738-44da-bb6e-15ab44004426n%40googlegroups.com.

Matthew Weiler

unread,
Oct 27, 2025, 5:43:01 AM (12 days ago) Oct 27
to HAPI FHIR
Hi James,
Thank you so much, you've saved my day :)

Adding  hapi-fhir-validation-resources-dstu3 solved my issue.
I'll try using a newer version of the HAPI FHIR libraries.

Do you happen to know if the HAPI FhirValidator is thread-safe?
We currently maintain a single instance of the  standard ValidationEngine and call it for each inbound request.
We do this as the time it takes to initialize an instance of the standard ValidationEngine is quite long.

I see that in the JavaDoc for the HAPI FhirValidator it says the below:
This class is thread safe, so you may register or unregister validator modules at any time. Individual modules are not guaranteed to be thread safe however. Reconfigure them with caution.
I'm not quite sure what it means by individual modules.
Should I be able to maintain a single instance of a HAPI FhirValidator and call it for all asynchronous inbound requests?
Or would I need to create a new instance of a HAPI FhirValidator for each  asynchronous inbound requests?

Cheers,
Matt

James Agnew

unread,
Oct 27, 2025, 5:46:07 AM (12 days ago) Oct 27
to Matthew Weiler, HAPI FHIR
The FhirInstanceValidator module is fully threadsafe, so assuming that's what you're using (and it should be), yes you can reuse your validator safely across threads.

Cheers,
James

Matthew Weiler

unread,
Oct 27, 2025, 8:25:19 AM (12 days ago) Oct 27
to James Agnew, HAPI FHIR
Thank you, sorry if I messaged you twice, I sent the one email but it didn't show up in the thread, so I didn't think it sent :p
Reply all
Reply to author
Forward
0 new messages