testcontainers / testcontainers/testcontainers-java
[Bug]: Unable to start container with mount as GraalVM native image
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 8.7k
- Forks
- 1.9k
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 9
Description
Module
Core
Testcontainers version
1.20.6
Using the latest Testcontainers version?
Yes
Host OS
Windows/WLS
Host Arch
x86
Docker version
Client:
Version: 28.0.4
API version: 1.48
Go version: go1.23.7
Git commit: b8034c0
Built: Tue Mar 25 15:06:08 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Desktop 4.0.0 ()
Engine:
Version: 28.0.4
API version: 1.48 (minimum version 1.24)
Go version: go1.23.7
Git commit: 6430e49
Built: Tue Mar 25 15:07:22 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.7.26
GitCommit: 753481ec61c7c8955a23d6ff7bc8e4daed455734
runc:
Version: 1.2.5
GitCommit: v1.2.5-0-g59923ef
docker-init:
Version: 0.19.0
GitCommit: de40ad0
What happened?
Hi,
please take a look at repo to reproduce at https://github.com/bedla/reproduce-graalvm-native-springboot-testcontainers
You can see that when running GraalVM native image, check for mount is failing.
It looks like that it is becase of prefix resource:.
Seems that there is missing pefix removal at org.testcontainers.utility.MountableFile#unencodeResourceURIToFilePath method?
Thank you
Ivos
Relevant log output
2025-04-22T13:50:55.790Z DEBUG 1 --- [demo] [ main] org.testcontainers.DockerClientFactory : Failure while checking for mountable file support
com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: mount denied:
the source path "resource:/org/testcontainers/utility/ResourceReaper.class:/dummy:ro"
too many colons
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247) ~[na:na]
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.post(DefaultInvocationBuilder.java:124) ~[na:na]
at org.testcontainers.shaded.com.github.dockerjava.core.exec.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:37) ~[na:na]
at org.testcontainers.shaded.com.github.dockerjava.core.exec.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:13) ~[na:na]
at org.testcontainers.shaded.com.github.dockerjava.core.exec.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:21) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.shaded.com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.shaded.com.github.dockerjava.core.command.CreateContainerCmdImpl.exec(CreateContainerCmdImpl.java:608) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.DockerClientFactory.runInsideDocker(DockerClientFactory.java:364) ~[na:na]
at org.testcontainers.DockerClientFactory.runInsideDocker(DockerClientFactory.java:351) ~[na:na]
at org.testcontainers.DockerClientFactory.checkMountableFile(DockerClientFactory.java:293) ~[na:na]
at org.testcontainers.DockerClientFactory.isFileMountingSupported(DockerClientFactory.java:99) ~[na:na]
at org.testcontainers.containers.ContainerDef.applyTo(ContainerDef.java:117) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.containers.GenericContainer.applyConfiguration(GenericContainer.java:783) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:381) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:346) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81) ~[na:na]
at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:336) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:322) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
at cz.publicstaticvoidmain.reproduce.demo.MyCommandLineRunner.run(DemoApplication.kt:54) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at org.springframework.boot.SpringApplication.lambda$callRunner$5(SpringApplication.java:788) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:82) ~[na:na]
at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:6.2.5]
at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:86) ~[na:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:796) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at org.springframework.boot.SpringApplication.lambda$callRunners$3(SpringApplication.java:772) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at java.base@21.0.6/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[na:na]
at java.base@21.0.6/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357) ~[na:na]
at java.base@21.0.6/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at java.base@21.0.6/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at java.base@21.0.6/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at java.base@21.0.6/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[na:na]
at java.base@21.0.6/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at java.base@21.0.6/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:772) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
at cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt.main(DemoApplication.kt:109) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
at java.base@21.0.6/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH) ~[na:na]
2025-04-22T13:50:55.790Z WARN 1 --- [demo] [ main] o.t.containers.ContainerDef : Unable to mount a file from test host into a running container. This may be a misconfiguration or limitation of your Docker environment. Some features might not work.
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with org.testcontainers.utility.MountableFile#unencodeResourceURIToFilePath and the mount check at DockerClientFactory#checkMountableFile. Run the linked GraalVM native-image reproduction and compare the mount source passed to Docker with the failing log. Done means the resource prefix is handled correctly and the container starts with the mount.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, java
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100