/bin/sh: 1: source: not found means a line written for bash was run by /bin/sh, which on Ubuntu is dash, and dash has no source command. Use . instead of source, or run the line with bash: in a Dockerfile add SHELL ["/bin/bash", "-c"], for a script use bash script.sh.

A Dockerfile RUN line is where this showed up as a hard failure: the build stopped with exit code 127. Run as sh load.sh, the same mistake did not stop the script at all.

The error

Get-Content l2\df1\Dockerfile
FROM ubuntu:24.04
RUN echo "NAME=Maria" > /tmp/app.env && source /tmp/app.env && echo "Hello $NAME"

docker build --no-cache --progress=plain -t fix10-lc-sh l2\df1
...
#5 [2/2] RUN echo "NAME=Maria" > /tmp/app.env && source /tmp/app.env && echo "Hello $NAME"
#5 0.205 /bin/sh: 1: source: not found
#5 ERROR: process "/bin/sh -c echo \"NAME=Maria\" > /tmp/app.env && source /tmp/app.env && echo \"Hello $NAME\"" did not complete successfully: exit code: 127
...

The same command in a script run with sh:

docker exec fix10-lc-u3 bash -c 'cat /root/load.sh; cat /root/app.env; ls -l /bin/sh'
#!/bin/bash
source /root/app.env
echo "Hello $NAME"
NAME=Maria
lrwxrwxrwx 1 root root 4 Mar 31  2024 /bin/sh -> dash

docker exec fix10-lc-u3 bash -c 'cd /root; sh load.sh 2>&1; echo exit=$?'
load.sh: 2: source: not found
Hello
exit=0

Why it happens

The error line itself names the shell: the build ran /bin/sh -c, and in the ubuntu:24.04 image /bin/sh is a link to dash, as the ls -l above shows. source works in bash (the fix below shows it); dash reported it as not found.

sh load.sh ignores the #!/bin/bash line: you asked sh to run the file, so sh did. In the script the failure was quiet: NAME stayed empty, the script printed Hello and exited with 0. In the Dockerfile the commands were joined with &&, so the failure stopped the step.

The fix

For a script, run it with bash:

docker exec fix10-lc-u3 bash -c 'cd /root; bash load.sh 2>&1; echo exit=$?'
Hello Maria
exit=0

For a Dockerfile, either switch the shell before the RUN line:

Get-Content l2\df2\Dockerfile
FROM ubuntu:24.04
SHELL ["/bin/bash", "-c"]
RUN echo "NAME=Maria" > /tmp/app.env && source /tmp/app.env && echo "Hello $NAME"

docker build --no-cache --progress=plain -t fix10-lc-sh l2\df2
...
#5 0.209 Hello Maria
#5 DONE 0.2s

or keep sh and use the dot command, which dash understands:

Get-Content l2\df3\Dockerfile
FROM ubuntu:24.04
RUN echo "NAME=Maria" > /tmp/app.env && . /tmp/app.env && echo "Hello $NAME"

docker build --no-cache --progress=plain -t fix10-lc-sh l2\df3
...
#5 0.248 Hello Maria
#5 DONE 0.3s

Both builds finished. With the SHELL line, the RUN line after it ran under bash in the test. The dot form also worked in a plain sh -c inside the container:

docker exec fix10-lc-u3 sh -c '. /root/app.env; echo Hello $NAME'
Hello Maria

How it was reproduced

The captures were made with Docker Engine 29.9.3 on the cached ubuntu:24.04 image (Ubuntu 24.04.5 LTS, bash 5.2.21): three small Dockerfiles built with docker build --no-cache --progress=plain -t fix10-lc-sh (image removed afterwards), and a container started with docker run -d --name fix10-lc-u3 ubuntu:24.04 sleep infinity, into which load.sh and app.env were copied with docker cp l3\load.sh fix10-lc-u3:/root/load.sh and the same for app.env. Every command was sent from Windows PowerShell 5.1 as shown, with any sh -c or bash -c text in single quotes so it reached the container unchanged; Get-Content is PowerShell printing the Dockerfile. The names are the test's own.

Frequently asked

Why does my Dockerfile say /bin/sh: 1: source: not found?
RUN lines run with /bin/sh -c, and in ubuntu:24.04 /bin/sh is dash, which has no source command. The build stopped with exit code 127 in the test.
How do I use source in a Dockerfile RUN line?
Add SHELL ["/bin/bash", "-c"] before the RUN line, or replace source with a dot. Both builds printed Hello Maria in the test.
Why does sh script.sh ignore #!/bin/bash?
Running sh script.sh tells sh to read the file, so the first line is only a comment. In the test sh load.sh failed on source while bash load.sh worked.

More decoded errors in the Fixes category.