DEV Community

anders lee
anders lee

Posted on

"exec /entrypoint.sh: no such file or directory" (but the file is right there)

You copy entrypoint.sh into the image, set it as the ENTRYPOINT, build, run, and get:

$ docker run --rm crlf-demo
exec /entrypoint.sh: no such file or directory
Enter fullscreen mode Exit fullscreen mode

You open a shell in the image and the file is exactly where it should be. The error message is technically true, but it's talking about a different file. Here are three errors from the same family, each reproduced on Docker Engine 29.9, with what they actually mean.

1. no such file or directory: the script has Windows line endings

This one hits almost everyone who builds images on Windows. Look at the bytes of the script:

$ od -c entrypoint.sh | head -n 2
0000000   #   !   /   b   i   n   /   s   h  \r  \n   e   c   h   o    
0000020   "   h   e   l   l   o       f   r   o   m       e   n   t   r
Enter fullscreen mode Exit fullscreen mode

The first line ends with \r \n (CRLF). When the kernel runs the script, it reads the interpreter from the shebang line up to the \n, so it looks for a program called /bin/sh\r, with an invisible carriage return at the end. That program doesn't exist, and the "no such file" in the error is about the interpreter, not your script.

Fixes, from most to least durable:

  • Tell Git to always check out shell scripts with LF. By default, Git for Windows converts text files to CRLF on checkout. Add a .gitattributes file at the repository root:
  *.sh text eol=lf
Enter fullscreen mode Exit fullscreen mode

Files you already have checked out keep their CRLF until you convert them once, so also fix the existing script.

  • In your editor, switch the file to LF. In VS Code, click CRLF in the status bar and choose LF.

  • As a safety net in the Dockerfile, strip the carriage returns while building:

  COPY entrypoint.sh /entrypoint.sh
  RUN sed -i 's/\r$//' /entrypoint.sh
Enter fullscreen mode Exit fullscreen mode

2. permission denied: the script isn't executable

Same setup, different error:

$ docker run --rm noexec-demo
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "/entrypoint.sh": permission denied
Enter fullscreen mode Exit fullscreen mode

The file has no execute bit. That's easy to miss when the script was created on a filesystem that doesn't store Unix permissions, or came out of a zip, a download or a CI artifact. Most of that long message is just the layers the error passed through (daemon → containerd shim → runc); the useful part is at the end.

The cleanest fix is to set the mode while copying, which needs no extra layer:

COPY --chmod=755 entrypoint.sh /entrypoint.sh
Enter fullscreen mode Exit fullscreen mode

On Linux or macOS you can also run chmod +x entrypoint.sh before building, and Git will keep that bit.

3. executable file not found in $PATH: the image doesn't have that shell

$ docker run --rm alpine:3.23 bash
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "bash": executable file not found in $PATH
Enter fullscreen mode Exit fullscreen mode

Alpine ships sh (BusyBox), not bash. The same error appears when the program in CMD is misspelled or was never copied into the image.

Use sh, or install bash explicitly:

RUN apk add --no-cache bash
Enter fullscreen mode Exit fullscreen mode

If your script uses bash-only syntax but starts with #!/bin/sh, it will run under BusyBox sh and fail in other, more confusing ways, so make the shebang match the shell you actually need.

A quick checklist

When a container won't start and the message mentions a file you can see:

  1. od -c script.sh | head -n 1: is there a \r before the \n?
  2. ls -l inside the image (docker run --rm --entrypoint ls image -l /entrypoint.sh): is there an x in the mode?
  3. Does the shebang's interpreter exist in the image? Try docker run --rm --entrypoint sh image -c 'command -v bash'.
  4. Read the error from the end: the last exec: ... part names the thing that actually failed.

I keep a page of nearly 30 common Docker errors like these, each reproduced with real output and a fix, as part of a free Docker tutorial: Docker error messages: causes and fixes.

Top comments (1)

Collapse
 
rushdeploy profile image
Rishabh Mishra •

The .gitattributes fix is the one I would keep. It stops the CRLF problem for the whole team, instead of fixing one file after each checkout.