This error occurs when the CMD or ENTRYPOINT instruction in a Dockerfile uses incorrect JSON array syntax. The fix is to ensure proper double quotes, commas between elements, and standard ASCII characters in the exec form.
The "/bin/sh: [npm,: not found" error indicates that Docker failed to parse your CMD or ENTRYPOINT instruction as a valid JSON array. When the exec form (array syntax) cannot be parsed as JSON, Docker falls back to shell form, passing the entire string to /bin/sh -c. The shell then tries to execute "[npm," as a command, which doesn't exist. This happens because the exec form requires strict JSON syntax: double quotes around each element, commas between elements, and standard ASCII characters. Common mistakes include using single quotes, forgetting commas, omitting quotes entirely, or copying code from sources that use "smart quotes" (curly quotes) instead of straight quotes. The error message reveals the problem: "[npm," appears as if it's trying to run a command literally named "[npm," rather than parsing "npm" as the first element of a JSON array.
Open your Dockerfile and locate the CMD or ENTRYPOINT instruction. Look for syntax issues:
Common incorrect patterns:
# Wrong: single quotes (JSON requires double quotes)
CMD ['npm', 'start']
# Wrong: missing commas
CMD ["npm" "start"]
# Wrong: no quotes at all
CMD [npm, start]
# Wrong: smart/curly quotes (often from copy-paste)
CMD [“npm”, “start”]
# Wrong: missing quotes on some elements
CMD ["npm", start]The error "/bin/sh: [npm,: not found" specifically indicates the array wasn't parsed as JSON, so Docker passed it to the shell literally.
Correct the CMD or ENTRYPOINT to use valid JSON array syntax with standard double quotes and commas:
# Correct: double quotes and commas
CMD ["npm", "start"]
# Correct: with arguments
CMD ["npm", "run", "dev"]
# Correct: ENTRYPOINT with CMD
ENTRYPOINT ["node"]
CMD ["server.js"]
# Correct: running a script
CMD ["./start.sh"]
# Correct: with full path
CMD ["/usr/local/bin/npm", "start"]Key rules for exec form:
- Use standard double quotes (") not single quotes or smart quotes
- Put a comma between each array element
- Each argument must be a separate array element
- The array is parsed as JSON, so follow JSON syntax strictly
If you copied your Dockerfile from a website, blog, or word processor, it may contain "smart quotes" that look similar but aren't valid JSON.
Check for smart quotes:
- Curly/smart quotes: “ ” ‘ ’
- Straight quotes (correct): " '
Fix using sed or your editor:
# Replace smart quotes in Dockerfile
sed -i 's/[“”]/"/g' Dockerfile
sed -i "s/[‘’]/'/g" DockerfileIn VS Code:
1. Open Find and Replace (Ctrl+H / Cmd+H)
2. Enable regex mode
3. Find: [“”] Replace: "
4. Click "Replace All"
Prevention: Always type Dockerfile commands manually or copy from plain text sources like official documentation or GitHub raw files.
If you don't need the benefits of exec form, you can use shell form instead, which is more forgiving:
# Shell form (no JSON parsing needed)
CMD npm start
# Shell form with multiple commands
CMD npm install && npm start
# Shell form allows variable expansion
CMD echo "Starting on port $PORT" && npm startWhen to use shell form:
- Simple commands without signal handling requirements
- Commands that need shell features (pipes, variable expansion, globbing)
- Quick prototyping
When to use exec form (recommended for production):
- Proper signal handling (SIGTERM for graceful shutdown)
- No shell overhead
- Predictable argument parsing
- Docker best practice for CMD and ENTRYPOINT
After fixing the syntax, rebuild and test your image:
# Rebuild the image
docker build -t myapp .
# Run and verify it starts correctly
docker run myapp
# Or run interactively to debug if needed
docker run -it myapp /bin/shVerify the instruction was parsed correctly:
# Inspect how Docker stored the CMD
docker inspect myapp --format='{{.Config.Cmd}}'
# Should show: [npm start] for exec form
# Not: [/bin/sh -c npm start] which indicates shell form fallbackIf Docker shows /bin/sh -c wrapping your command, it means the exec form wasn't parsed correctly and fell back to shell form.
Exec form vs Shell form internals: When you use exec form CMD ["npm", "start"], Docker directly executes the binary without a shell wrapper. The process runs as PID 1 and receives signals directly. Shell form CMD npm start runs as /bin/sh -c "npm start", meaning /bin/sh is PID 1 and may not forward signals to your application.
JSON parsing behavior: Docker's JSON parser is strict. If parsing fails, it silently falls back to shell form. This is why CMD ['npm', 'start'] (single quotes) doesn't error during build—Docker treats it as shell form, passing the literal string ['npm', 'start'] to /bin/sh.
Escaping special characters: If your command includes quotes or special characters, escape them properly:
# Running a command with JSON argument
CMD ["node", "-e", "console.log(\"Hello\")"]
# Or use shell form to avoid escaping
CMD node -e 'console.log("Hello")'ENTRYPOINT + CMD combination: When both are in exec form, CMD arguments are appended to ENTRYPOINT:
ENTRYPOINT ["npm"]
CMD ["start"]
# Runs: npm start
# Override CMD at runtime:
# docker run myapp run test
# Runs: npm run testDebugging parse issues: To see exactly how Docker interprets your instruction:
docker history myapp --no-trunc | grep -E "CMD|ENTRYPOINT"Windows considerations: On Windows containers, the default shell is cmd /S /C instead of /bin/sh -c. Use exec form for cross-platform Dockerfiles.
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
Error response from daemon: manifest for nginx:nonexistent not found: manifest unknown: manifest unknown
How to fix 'manifest for image:tag not found' in Docker
Error response from daemon: invalid reference format: repository name must be lowercase
How to fix 'repository name must be lowercase' in Docker
Error response from daemon: No such image
How to fix 'No such image' in Docker
Error response from daemon: Container is not running
How to fix 'Container is not running' when using docker exec