exec /app/run.sh: exec format error when a container starts means the kernel was asked to execute a file it does not know how to run. For a shell script used as an exec-form ENTRYPOINT, the usual reason is a missing first line: add #!/bin/sh at the top of the script and rebuild.

Alternatively, start the script through the shell, so sh reads it; with --entrypoint sh the same image printed its line, as shown below. The shebang is the cleaner fix because the script then runs the same way everywhere.

The error

docker run --rm --name fix8-bld-r7 fix8-bld-q7
exec /app/run.sh: exec format error

The container exited with code 255 and printed nothing else. The build itself had succeeded with exit code 0, so nothing warned about the problem until the first run.

Why it happens

The Dockerfile copied the script, made it executable and used it as the entry point:

FROM alpine
COPY run.sh /app/run.sh
RUN chmod +x /app/run.sh
ENTRYPOINT ["/app/run.sh"]

The script's only line was echo "hello from run.sh". With the exec form, Docker hands /app/run.sh straight to the kernel's exec, with no shell in between. The kernel recognises a compiled program by its header and a script by a first line starting with #! that names the interpreter. A text file with neither is not a format it can execute, so the call fails with "exec format error".

Run through a shell, the same image worked: docker run --rm --name fix8-bld-r7h --entrypoint sh fix8-bld-q7 -c /app/run.sh printed hello from run.sh and exited with 0, and so did --entrypoint sh fix8-bld-q7 /app/run.sh. A script that works when you call it from a terminal can still fail as an exec-form entry point.

The fix

#!/bin/sh
echo "hello from run.sh"
docker run --rm --name fix8-bld-r7f fix8-bld-q7fix
hello from run.sh

Only the script changed; the Dockerfile stayed the same. The container printed its line and exited with code 0.

How it was reproduced

The four-line Dockerfile above on alpine with a one-line run.sh saved with LF line endings, built with docker build --progress=plain -t fix8-bld-q7 fix8-bld-q7 and run with docker run on Docker Desktop engine 29.9.2; then the same files with the shebang added, built into fix8-bld-q7fix. Tags and folders are this test's own.

Frequently asked

What does exec format error mean for a Docker entrypoint script?
The kernel could not execute the script, here because its first line #!/bin/sh was missing. An image built for another CPU architecture is another common cause, not tested here.
How do I fix exec format error for an entrypoint script?
Add #!/bin/sh as the first line of the script and rebuild, or start it through the shell, for example docker run --entrypoint sh image /app/run.sh.
Why does the script work in my terminal but not as ENTRYPOINT?
Exec-form ENTRYPOINT runs the file without a shell, and in the test the same file ran when started through sh. A shebang tells the kernel which interpreter to use.

More decoded errors in the Fixes category. If the script has a shebang and still fails with "no such file or directory", see the CRLF entrypoint post.