Fix the “Error: EACCES: permission denied, mkdir ‘/home/node/.n8n’” when running n8n in Docker inside an LXC on Proxmox VE

Before you start: versions, package names and storage identifiers change over time. Check the commands against the official documentation for your setup before running them, especially anything that creates, deletes or overwrites data.

docker compose down
  • Identify the host directory that is bind‑mounted to /home/node/.n8n inside the container. Open the compose file with your preferred editor and look for a line similar to:

    More Tutorials & Self-Hosting guides on TechPulseMind →

    volumes:
      - ./n8n_data:/home/node/.n8n
    

    Explanation: The left side of the colon (./n8n_data) is the path on the host relative to where you ran docker compose up. The right side (/home/node/.n8n) is the mount point inside the container. If you used an absolute path, note that instead.

  • Change ownership of that host directory to UID 1000 and GID 1000, which correspond to the node user used by the n8n image.

    Explanation: The chown command changes the user and group ownership of files and directories. The -R flag makes the change recursive, affecting all existing contents of the directory. Running it with sudo is necessary because the directory is likely owned by root.

    sudo chown -R 1000:1000 ./n8n_data
    
  • (Optional) Verify that the ownership change succeeded.

    Explanation: ls -ld shows the details of the directory itself, not its contents. The output should list the user and group IDs as 1000.

    ls -ld ./n8n_data
    

    You should see something like:

    drwxr-xr-x 2 1000 1000 4096 Sep 26 10:12 ./n8n_data
    
  • Start the n8n stack again.

    Explanation: docker compose up -d recreates the containers in detached mode, using the updated permissions on the bind‑mount.

    docker compose up -d
    
  • Check the container logs to confirm the error is gone.

    Explanation: docker logs -f <container-id> streams the logs of the n8n container. Replace <container-id> with the actual ID or name you see from docker ps. You should see the startup message indicating that n8n is ready.

    docker logs -f n8n
    

    Look for a line similar to:

    n8n ready on http://0.0.0.0:5678
    
  • Verification

    1. Confirm that the container is running.

      Explanation: docker ps lists all containers that are currently in the Up state. The n8n service should appear with a status like Up X minutes.

      docker ps
      
    2. Access the n8n web interface from a browser.

      Explanation: By default n8n listens on port 5678 inside the container, and the compose file typically maps that to the same port on the host. Open http://<proxmox-host-ip>:5678 (replace <proxmox-host-ip> with the IP address of your Proxmox node or the LXC’s IP if you forwarded the port). You should see the n8n setup or login screen.

    3. Ensure no permission errors appear in the logs.

      Explanation: Run docker logs n8n (without -f to get a static output) and scan for the string EACCES or permission denied. There should be none.

      docker logs n8n
      
    4. Test data persistence.

      Explanation: Create a simple workflow, stop the stack with docker compose down, then start it again with docker compose up -d. After the container is healthy, open the workflow you created; it should still be present.

    Troubleshooting the Most Common Failures

    • Container still exits immediately after up
      If you still see the EACCES error, double‑check that you changed ownership of the exact directory referenced in the compose file. A common mistake is to chown a parent folder or a differently named folder. Run ls -l in the directory containing the compose file to confirm the folder name and its ownership.

    • Permission denied on sub‑folders inside the data directory
      If the top‑level directory is owned correctly but you still get errors about sub‑folders (for example, .n8n/database), run the chown command again with the -R flag to ensure recursion applied to all nested items.

    • UID/GID mismatch because the image changed
      The official n8n image uses the node user (UID 1000, GID 1000) as of the time of writing, but you should verify this for the specific tag you are using. Consult the image’s Docker Hub page or the official n8n documentation for the exact user IDs. If they differ, substitute the correct numbers in the chown command.

    • Docker inside LXC shows shifted IDs
      In an unprivileged LXC the host’s UID 0 is mapped to a high range inside the container, but permission checks on bind‑mounts still use the host’s ownership. The fix described above works regardless of the mapping because we align the host‑side ownership with the container’s expected UID/GID. No additional LXC configuration is required.

    • Accidentally removed data while troubleshooting
      If you deleted the host directory thinking it would be recreated, you will lose any persisted workflows or credentials. Always back up the ./n8n_data folder (or whatever you named it) before experimenting with rm -rf or similar destructive commands.

    Conclusion

    By ensuring that the host‑side directory used for n8n’s persistent data is owned by UID 1000 and GID 1000, you eliminate the Error: EACCES: permission denied, mkdir '/home/node/.n8n' that occurs when the image runs as the non‑root node user inside Docker. The procedure takes only a few minutes, requires no changes to the compose file, and preserves all existing data. Once the container is up, you can access the n8n UI at port 5678 and begin building automations.

    For future deployments, make it a habit to set the correct ownership immediately after creating any bind‑mount folder that a non‑root image will write to. If you prefer to avoid manual steps, you can run the container as root (user: "0:0") but this reduces the security isolation that the node user provides. Refer to the official n8n Docker documentation for the most up‑to‑date user IDs and any changes to the image’s default user.

    Frequently Asked Questions

    Why does the error only appear when Docker runs inside an LXC on Proxmox?

    The n8n image expects to write to /home/node/.n8n as the node user (UID 1000). In an unprivileged LXC the host’s UID 0 is mapped to a different range inside the container, but permission checks on bind‑mounts still follow the host’s ownership. If the host folder is owned by root, the node user lacks write rights, causing the mkdir to fail.

    Can I fix the problem by changing the compose file instead of the host folder?

    Yes. You could add user: "0:0" to the n8n service to run the container as root, which would bypass the permission check. However, this runs the container with full privileges inside the LXC and is not recommended for production environments where isolation matters.

    What if I want to use a named volume instead of a bind mount?

    Named volumes are managed by Docker and are created with the correct ownership for the image’s user, so the permission error does not occur. To switch, replace the bind‑mount line in the compose file with something like - n8n_data:/home/node/.n8n and declare the volume under the volumes: top‑level key. Remember that named volumes are less transparent for direct host‑side backups.

    How do I find the exact UID/GID that the n8n image uses for my specific tag?

    Check the image’s Docker Hub page or the official n8n documentation for the node user details. You can also inspect the image directly with docker run --rm <image> id (replace <image> with the full image reference) to see the UID and GID reported inside the container.

    Some links on this page may be affiliate links. If you buy through them we may earn a commission at no extra cost to you. See our affiliate disclosure.

    How to Expose Your Home Server with Cloudflare TunnelRead next