error nodejs
Node.js EACCES
Understanding Node.js EACCES error - permission denied when accessing a file, directory, or port.
What It Means
EACCES stands for “Error: ACCESs denied.” This error occurs when Node.js tries to access a file, directory, or network resource but is denied by filesystem permissions. Common scenarios include reading files without read permission, writing to protected directories, or binding to a privileged port (< 1024).
Common Causes
- Trying to listen on ports below 1024 (e.g., 80, 443) without root
- Reading or writing files without proper filesystem permissions
- npm global install without proper permissions
- Accessing files owned by another user
- Docker container running as wrong user
- Node.js modules directory has wrong ownership
How to Fix
Fix port access
// Error: listen EACCES: permission denied 0.0.0.0:80
// Option 1: Use a non-privileged port
const PORT = process.env.PORT || 3000;
app.listen(PORT);
// Option 2: Use a reverse proxy (recommended for production)
// Nginx listens on 80 and proxies to your Node.js app on 3000
# Option 3: Allow Node.js to bind to low ports (Linux)
sudo setcap 'cap_net_bind_service=+ep' $(which node)
# Option 4: Use authbind
sudo apt install authbind
sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80
sudo chown $(whoami) /etc/authbind/byport/80
authbind node app.js
Fix file permission errors
# Check file permissions
ls -la /path/to/file
# Fix ownership
sudo chown $(whoami) /path/to/file
# Fix permissions
chmod 644 /path/to/file # Read/write for owner, read for others
chmod 755 /path/to/directory # Includes execute for directories
Fix npm global installation
# Option 1: Fix npm directory permissions
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
# Add to ~/.bashrc or ~/.zshrc:
export PATH=~/.npm-global/bin:$PATH
# Option 2: Fix existing permissions
sudo chown -R $(whoami) /usr/local/lib/node_modules
sudo chown -R $(whoami) /usr/local/bin
# Option 3: Use npx instead of global installs
npx create-react-app my-app # Instead of globally installing CRA
Handle in code
const fs = require('fs/promises');
async function readConfig(path) {
try {
return await fs.readFile(path, 'utf-8');
} catch (error) {
if (error.code === 'EACCES') {
console.error(`Permission denied reading ${path}`);
console.error('Check file permissions: ls -la ' + path);
// Fall back to default config
return '{}';
}
throw error;
}
}
Fix in Docker
FROM node:20-alpine
WORKDIR /app
# Create writable directories with proper ownership
RUN mkdir -p /app/uploads /app/logs && \
chown -R node:node /app
COPY --chown=node:node package*.json ./
RUN npm ci
COPY --chown=node:node . .
USER node
CMD ["node", "app.js"]
Fix CI/CD permission issues
# GitHub Actions
steps:
- name: Fix permissions
run: |
chmod +x ./scripts/deploy.sh
chmod -R 755 ./dist
- name: Run deploy
run: ./scripts/deploy.sh
Related Errors
- Node.js EPERM - Operation not permitted (system-level restriction, not file permissions).
- Node.js ENOENT - File doesn’t exist at all.
- Node.js EADDRINUSE - Port already in use (not a permission issue).