Skip to content

fix(kafka): use sentinel file to eliminate starter-script race condition (#11682) - #11957

Draft
klouds27 wants to merge 1 commit into
testcontainers:mainfrom
klouds27:feat/11682-kafka-starter-script-race
Draft

fix(kafka): use sentinel file to eliminate starter-script race condition (#11682)#11957
klouds27 wants to merge 1 commit into
testcontainers:mainfrom
klouds27:feat/11682-kafka-starter-script-race

Conversation

@klouds27

@klouds27 klouds27 commented Aug 3, 2026

Copy link
Copy Markdown

The Kafka containers start the broker by writing a startup script into the container via copyFileToContainer, then executing it with a shell loop that polls for the file. Because the loop checks only for file existence, it can detect the script the instant its inode is created and attempt to execute it before the write completes. On busy hosts this produces Text file busy (ETXTBSY) and a container exit code of 126.

This was confirmed in #11682 by the reporter and a second commenter. The suggestion of checking file size with [ -s file ] was also tested and failed for the same reason: size becomes non-zero before the write finishes.

The fix introduces a sentinel file (/tmp/testcontainers_start.sh.ready) that is created via execInContainer("touch", ...) only after copyFileToContainer returns. The wait loop now polls for the sentinel instead of the script itself. Because copyFileToContainer completes fully before the sentinel is touched, the loop cannot proceed until the script is both fully written and closed.

The change is applied consistently to all affected containers: org.testcontainers.kafka.KafkaHelper (shared COMMAND constant), org.testcontainers.kafka.KafkaContainer, org.testcontainers.kafka.ConfluentKafkaContainer, and the deprecated org.testcontainers.containers.KafkaContainer.

Fixes #11682

…ion (testcontainers#11682)

copyFileToContainer writes the startup script into the container over a Docker
API call. On busy hosts the wait loop can detect the file the moment its inode
is created, before the write completes, and attempt to execute an incomplete
file. This produces ETXTBSY and exit code 126.

The fix adds a sentinel file (STARTER_SCRIPT + ".ready") that is touched via
execInContainer only after copyFileToContainer returns. The wait loop now checks
for the sentinel instead of the script itself, so execution cannot begin until
the script is fully written.

Applied to KafkaHelper, org.testcontainers.kafka.KafkaContainer,
org.testcontainers.kafka.ConfluentKafkaContainer, and the deprecated
org.testcontainers.containers.KafkaContainer.

Signed-off-by: klouds27 <adalwolf@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Kafka container fails with 'Container exited with code 126' due to a race between command wait loop and script installation

1 participant