Troubleshoot

ERPNext Troubleshooting: Fix the 12 Most Common Errors (2026)

July 16, 202620 min read· by Manoj

ERPNext troubleshooting is 80% pattern recognition. After six years of implementing and supporting ERPNext for Indian SMEs, I have seen the same dozen errors appear across manufacturing, distribution, and service businesses. This guide covers each one with the actual fix — the exact command, the specific setting, the precise file to edit. No "contact support" dead ends. If your ERPNext instance is broken right now, find your error below and follow the steps.

Short answer

The most common ERPNext errors fall into six categories: server errors (500/Internal Server Error), bench update and migration failures, database deadlocks under concurrent load, PDF generation failures (wkhtmltopdf), stock and GL ledger mismatches, and version upgrade breakage. Most are fixable in under 30 minutes with the right command. This guide covers all six categories with step-by-step fixes verified on ERPNext v15 and v16.

How do I find the actual error message in ERPNext?

Before fixing anything, you need to read the actual error — not the generic "Something went wrong" screen. ERPNext hides Python tracebacks from end users for security, but they are always logged.

Four ways to find the real error:

  1. Browser developer tools — press F12, go to the Network tab, reproduce the error, and click the failed request (red, usually 500 status). The Response tab shows the full Python traceback.

  2. Frappe error log — in ERPNext, go to the URL bar and type /app/error-log. This page lists every server-side error with the full traceback, timestamp, and the user who triggered it.

  3. Bench logs — on the server, run tail -100 ~/frappe-bench/logs/frappe.log to see recent errors. For worker errors (background jobs), check tail -100 ~/frappe-bench/logs/worker.error.log.

  4. Bench console — run bench --site yoursite.com console to get a Python shell inside your site's context. Useful for testing specific operations and reading error messages directly.

Skimmable summary: ERPNext troubleshooting starts with reading the actual traceback. F12 Network tab, /app/error-log, or bench logs — one of these will show the real error within 30 seconds.

How do I fix ERPNext Internal Server Error (500)?

Internal Server Error is the most common ERPNext error and the least descriptive. It means Python raised an unhandled exception. The fix depends on what the traceback says.

Common causes and fixes:

Missing or corrupt site_config.json

Symptom: 500 error on every page, including the login page.

Fix: Check that ~/frappe-bench/sites/yoursite.com/site_config.json exists and contains valid JSON with at least db_name, db_password, and db_type. A common cause is accidentally editing the file with a Windows text editor that adds BOM characters.

cat ~/frappe-bench/sites/yoursite.com/site_config.json

If the file is corrupt, restore it from backup or recreate it with the correct database credentials.

MariaDB connection refused

Symptom: OperationalError: (2002, "Can't connect to local MySQL server") in the traceback.

Fix: MariaDB is not running. Start it:

sudo systemctl start mariadb
sudo systemctl enable mariadb

If MariaDB crashes repeatedly, check /var/log/mysql/error.log for the reason — usually disk space full or InnoDB corruption.

Redis connection error

Symptom: ConnectionError: Error connecting to Redis or redis.exceptions.ConnectionError.

Fix: Redis is not running. ERPNext uses three Redis instances (cache, queue, socketio):

sudo systemctl start redis-server

Or restart all services: sudo supervisorctl restart all

Permission denied errors

Symptom: frappe.exceptions.PermissionError in the traceback, but the user should have access.

Fix: The user's role does not have the required permission. Go to Setup → Role Permission Manager, find the DocType mentioned in the error, and check that the user's role has Read/Write/Create permissions as needed. Do not solve this by giving Administrator access — fix the specific role permission.

Skimmable summary: ERPNext troubleshooting for 500 errors = read the traceback. site_config.json corrupt → fix JSON. MariaDB down → start it. Redis down → restart services. Permission error → fix the role, not the user.

How do I fix bench update failures?

bench update is how you keep ERPNext current. When it fails, it usually fails loudly with a specific error. Here are the common failure patterns.

Git merge conflict on custom changes

Symptom: error: Your local changes to the following files would be overwritten by merge

Fix: You have uncommitted changes in the apps directory (usually from direct code edits). Back up your changes, then:

cd ~/frappe-bench/apps/erpnext
git stash
cd ~/frappe-bench
bench update

After the update, review whether your stashed changes are still needed. If they are custom modifications, move them to a custom app instead of editing core files directly — core edits will break on every update.

Node.js version mismatch

Symptom: error engine: incompatible with this module or SyntaxError: Unexpected token during asset build.

Fix: ERPNext v16 requires Node.js 20+. Check your version:

node --version

If it is below 20, update Node.js using nvm:

nvm install 20
nvm use 20
nvm alias default 20
bench setup env
bench build

Python dependency error

Symptom: ModuleNotFoundError or ImportError after update.

Fix: The Python virtual environment is out of sync. Rebuild it:

bench setup env
bench pip install -e apps/frappe
bench pip install -e apps/erpnext

Migration failed

Symptom: bench update succeeds on code pull but fails on bench migrate with a database error.

Fix: Read the specific migration error. Common cases:

  • Duplicate column: A custom field conflicts with a new standard field. Remove the custom field first, then re-migrate.
  • Table doesn't exist: A required app was not installed. Run bench --site yoursite.com install-app [appname].
  • Timeout: Large tables with many rows take time to alter. Increase MariaDB timeout: add wait_timeout=28800 to /etc/mysql/my.cnf and restart MariaDB.

Golden rule: Always run bench --site yoursite.com backup before bench update. If the update fails badly, restore:

bench --site yoursite.com restore ~/frappe-bench/sites/yoursite.com/private/backups/[latest-backup].sql.gz

Skimmable summary: git conflict → stash and update. Node.js wrong → nvm install 20. Python missing → bench setup env. Migration failed → read the error, fix the specific conflict. Always backup first.

How do I fix database deadlocks in ERPNext?

Deadlocks are the scariest ERPNext error because they seem random. They are not. A deadlock happens when two database transactions each wait for a lock the other holds. ERPNext triggers this under specific concurrent-write patterns.

Common deadlock triggers:

  1. Bulk Stock Entry via API — submitting 200+ stock entries simultaneously through a script or integration. Each entry locks multiple rows in tabStock Ledger Entry and tabGL Entry.

  2. Bulk payment reconciliation — reconciling 60+ invoices at once. Each reconciliation updates the invoice status, payment entry, and GL entries.

  3. Concurrent customer/address updates via API — external systems syncing customer data through /api/resource/Customer while users edit the same records in the UI.

The fix pattern:

Reduce concurrency:

  • Lower gunicorn workers if you recently increased them. More workers = more concurrent database writes = more deadlock potential. For a 25-user setup, 4–5 workers is usually optimal. Edit ~/frappe-bench/config/supervisor.conf or Procfile.
  • Use bench config set gunicorn_workers 4 and sudo supervisorctl restart all.

Serialise bulk operations:

  • Instead of submitting 200 stock entries via API simultaneously, submit them in batches of 10–20 with a 1-second delay between batches.
  • For payment reconciliation, process in smaller batches (20–30 invoices at a time).

Increase lock wait timeout (temporary relief, not a fix):

# In /etc/mysql/my.cnf under [mysqld]
innodb_lock_wait_timeout = 120

Restart MariaDB after changing. This gives transactions more time to acquire locks but does not eliminate the root cause.

Monitor deadlocks:

# In MariaDB console
SHOW ENGINE INNODB STATUS\G

Look for the LATEST DETECTED DEADLOCK section. It shows exactly which two transactions conflicted and which tables/rows were involved.

Skimmable summary: deadlocks = concurrent writes fighting for the same rows. Fix by reducing gunicorn workers, batching bulk operations, and monitoring with SHOW ENGINE INNODB STATUS. More workers is not always better.

How do I fix PDF generation errors in ERPNext?

PDF generation in ERPNext uses wkhtmltopdf (a command-line tool that converts HTML to PDF). When it breaks, invoices, delivery notes, and reports cannot be printed or emailed.

Error 1: "wkhtmltopdf not found" or "ConnectionRefusedError"

Fix: wkhtmltopdf is not installed or not in the system PATH.

# Check if installed
which wkhtmltopdf

# Install on Ubuntu 22.04/24.04
sudo apt install wkhtmltopdf

# If installed but not found, create a symlink
sudo ln -s /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf

If you are using Supervisor, the PATH in the Supervisor config may not include /usr/local/bin. Add it to the Supervisor environment or create the symlink above.

Error 2: "Invalid wkhtmltopdf version"

Fix: Frappe requires wkhtmltopdf with the patched Qt version (0.12.6+). The version from apt install on older Ubuntu may be unpatched. Download the patched version from the wkhtmltopdf releases page:

wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
sudo dpkg -i wkhtmltox_0.12.6.1-3.jammy_amd64.deb

Error 3: PDFs render with broken layout or missing fonts

Fix: Install the fonts your print format uses. For Indian invoices with Hindi/Marathi/Tamil text:

sudo apt install fonts-noto fonts-noto-cjk fonts-noto-extra

Also check that host_name in site_config.json is set correctly. wkhtmltopdf fetches CSS from this URL during PDF generation — if it points to localhost but the site runs on a domain, stylesheets will not load.

{
  "host_name": "https://erp.yourcompany.com"
}

Alternative: headless Chrome (Frappe v15+):

Newer Frappe versions support headless Chrome for PDF generation instead of wkhtmltopdf. If wkhtmltopdf keeps causing issues:

# Install Chrome
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
sudo apt update && sudo apt install google-chrome-stable

# In site_config.json
{
  "pdf_engine": "chrome"
}

Skimmable summary: wkhtmltopdf not found → install or symlink. Wrong version → install patched 0.12.6+. Broken layout → install fonts and fix host_name. Or switch to headless Chrome with "pdf_engine": "chrome" in site_config.json.

How do I fix stock and GL ledger mismatches?

Stock-GL mismatch means the inventory value in your Stock Ledger does not match the corresponding GL entries in your accounting books. This is the error that CFOs lose sleep over.

How to detect it:

Run the Stock and Account Value Comparison report (Stock → Reports → Stock and Account Value Comparison). Any row where the stock value and account value differ is a mismatch.

Common causes:

  1. Backdated transactions — posting a stock entry dated three months ago recalculates stock values from that date forward. If the GL was not reposted, the ledgers diverge.

  2. Cancelled-then-amended entries — cancelling a submitted document and amending it can leave orphaned GL entries if the process is interrupted (browser closed, timeout, server restart).

  3. Direct database edits — anyone who edited tabStock Ledger Entry or tabGL Entry directly in the database has broken the chain. Never edit these tables directly.

  4. Rounding differences — rare but possible with multi-currency transactions where exchange rate precision causes ₹0.01 differences that accumulate.

How to fix it:

Step 1: Identify the affected items and warehouses from the Stock and Account Value Comparison report.

Step 2: Repost stock ledger entries:

Go to the URL bar → /app/repost-item-valuation/new. Select the item, warehouse, and the date from which the mismatch started. Submit it. ERPNext will recalculate all stock valuations from that date forward.

Step 3: Repost GL entries:

After stock reposting completes, go to /app/repost-accounting-ledger/new. Select the company and date range. This regenerates GL entries to match the corrected stock values.

Step 4: Verify by running the Stock and Account Value Comparison report again.

Prevention:

  • Avoid backdated transactions. If you must backdate, repost immediately.
  • Never edit stock or GL tables directly in the database.
  • Run the comparison report monthly as part of your month-end close.

For detailed costing troubleshooting, see the ERPNext standard costing guide and landed cost voucher guide.

Skimmable summary: stock-GL mismatch → run Stock and Account Value Comparison report → repost item valuation → repost accounting ledger → verify. Prevent by avoiding backdated entries and never editing ledger tables directly.

How do I fix ERPNext v16 upgrade errors?

Upgrading from v15 to v16 is the most error-prone operation in the ERPNext lifecycle right now. V16 has hard environment requirements that v15 did not.

Mandatory requirements for v16:

Requirementv15v16
Python3.10–3.113.12+ (mandatory)
Node.js18 LTS20 LTS+
MariaDB10.6+10.6+ (unchanged)
Redis6.0+6.0+ (unchanged)

Error 1: SyntaxError on Python 3.11

Symptom: SyntaxError: invalid syntax in Frappe code after switching to v16 branch.

Fix: v16 uses Python 3.12 syntax features. Upgrade Python:

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.12 python3.12-venv python3.12-dev
bench setup env --python python3.12
bench pip install -e apps/frappe
bench pip install -e apps/erpnext

Error 2: Asset build fails with Node.js 18

Symptom: bench build fails with webpack/esbuild errors after switching to v16.

Fix: Upgrade Node.js to 20:

nvm install 20
nvm use 20
nvm alias default 20
bench build

Error 3: "App 'payments' not found" during migration

Symptom: bench migrate fails with Could not find app 'payments' or similar missing-app error.

Fix: v16 split some functionality into separate apps. Install the missing app:

bench get-app payments --branch version-16
bench --site yoursite.com install-app payments
bench --site yoursite.com migrate

Error 4: Custom fields conflict with new standard fields

Symptom: DuplicateColumnError during migration — a custom field you created in v15 now exists as a standard field in v16.

Fix: Before upgrading, list your custom fields (/app/custom-field?standard=No) and compare against the v16 changelog. Remove any custom field that v16 now includes as standard, then run bench migrate.

The safe upgrade path:

  1. Back up everything: bench --site yoursite.com backup --with-files
  2. Fix all pending errors on v15 first — run bench migrate on v15 and resolve any issues
  3. Upgrade Python to 3.12 and Node.js to 20
  4. Switch branches: bench switch-to-branch version-16 frappe erpnext hrms payments
  5. Run bench setup env --python python3.12
  6. Run bench --site yoursite.com migrate
  7. Run bench build
  8. Test critical workflows before letting users in

For the complete upgrade walkthrough, see the v15 to v16 upgrade guide.

Skimmable summary: v16 needs Python 3.12+ and Node.js 20+. Most upgrade errors are environment mismatches, not code bugs. Fix v15 issues first, upgrade Python/Node, then switch branches and migrate.

How do I fix ERPNext email sending errors?

Email failures are silent killers — invoices not reaching customers, notifications not reaching approvers, and password resets not working. ERPNext sends email through configured SMTP accounts.

Error 1: "Email account not configured"

Fix: Go to Setup → Email Account. Create an account with your SMTP credentials. For Gmail: SMTP server smtp.gmail.com, port 587, use TLS. You must generate an App Password (Gmail Settings → Security → App passwords) — regular passwords do not work with 2FA enabled.

Error 2: "Authentication failed"

Fix: The email password is wrong or expired. For Gmail, regenerate the App Password. For custom domains, check with your email provider. Update the password in Setup → Email Account → [your account].

Error 3: Emails stuck in queue

Symptom: Emails appear in Email Queue (/app/email-queue) with status "Not Sent" or "Error".

Fix: Check that the email worker is running:

bench doctor

If bench doctor shows background workers are not running:

sudo supervisorctl status
sudo supervisorctl restart all

If workers are running but emails are stuck, click on a failed email in the queue to see the error message. Common causes: SMTP rate limiting (too many emails per minute), attachment too large, or recipient address invalid.

Error 4: Emails going to spam

Fix: Configure SPF, DKIM, and DMARC records for your sending domain. Without these, Gmail and Outlook classify your emails as spam. This is a DNS configuration issue, not an ERPNext issue.

Skimmable summary: email errors → check Email Account config, verify SMTP credentials (use App Password for Gmail), ensure background workers are running (bench doctor), and set up SPF/DKIM/DMARC to avoid spam folders.

How do I fix ERPNext scheduler and background job errors?

The scheduler runs recurring tasks — sending email digests, processing auto-repeat invoices, syncing integrations, and running scheduled reports. When it stops, these tasks silently stop too.

Error 1: "Scheduler is disabled"

Symptom: Recurring tasks stop running. Check at Setup → Scheduler Log or run:

bench doctor

Fix: Enable the scheduler:

bench --site yoursite.com enable-scheduler

The scheduler gets disabled automatically when bench update encounters an error. Always check scheduler status after a failed update.

Error 2: Background jobs stuck or failing

Symptom: Jobs pile up in /app/background-jobs with status "queued" and never complete.

Fix: Restart the workers:

sudo supervisorctl restart all

If jobs keep failing, check the worker error log:

tail -50 ~/frappe-bench/logs/worker.error.log

Common causes: a specific background job throws an unhandled exception and blocks the queue. Find the failing job in Background Jobs, note the error, and fix the underlying issue.

Error 3: Cron jobs not triggering

Fix: ERPNext uses the Frappe scheduler, not system cron. But the scheduler itself is triggered by a system cron entry. Check it exists:

crontab -l

You should see a line like:

*/5 * * * * cd /home/frappe/frappe-bench && bench schedule

If missing, add it: bench setup cron

Skimmable summary: scheduler disabled → bench enable-scheduler. Jobs stuck → restart workers and check worker.error.log. Cron missing → bench setup cron. Always check scheduler status after failed updates.

How do I fix ERPNext performance issues?

ERPNext troubleshooting for performance is different from fixing errors — slow ERPNext is a symptom, not a single problem. The fix depends on whether the bottleneck is the database, the application server, or the client browser.

Step 1: Identify the bottleneck

  • Slow page loads for all users → server-side issue (database or application)
  • Slow for one user, fast for others → browser cache, network, or that user's data volume
  • Slow on specific reports → database query optimisation needed
  • Slow after a specific date → a recent change or data volume crossing a threshold

Database bottlenecks (most common):

# Check slow queries
tail -100 /var/log/mysql/slow.log

# Or enable slow query logging
# In /etc/mysql/my.cnf under [mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

Common fixes:

  • Add missing indexes — run bench --site yoursite.com migrate (migrations add needed indexes)
  • Increase innodb_buffer_pool_size to 50–70% of available RAM in /etc/mysql/my.cnf
  • Archive old transactions — move completed orders older than 2 years to a separate company or export and delete

Application bottlenecks:

  • Increase gunicorn workers (but not too many — see the deadlock section above). Rule of thumb: (2 × CPU cores) + 1
  • Enable Redis caching — verify Redis is running and redis_cache is set in common_site_config.json
  • Check for runaway background jobs consuming CPU — bench doctor and sudo supervisorctl status

Client-side bottlenecks:

  • Clear browser cache — ERPNext caches aggressively and old cached files can cause issues after updates
  • Disable browser extensions — some ad blockers interfere with ERPNext's API calls
  • Use Chrome or Firefox — ERPNext is optimised for these browsers

For hosting infrastructure sizing, see the ERPNext hosting cost guide.

Skimmable summary: identify whether the bottleneck is database (slow queries, buffer pool), application (workers, Redis), or client (cache, browser). Most slow ERPNext instances are under-provisioned on MariaDB buffer pool or have too many gunicorn workers causing deadlocks.

How do I fix ERPNext login issues?

ERPNext troubleshooting for login failures is the most panic-inducing category because they lock out every user including the Administrator.

Error 1: "frappe.boot is undefined" or blank login page

Symptom: The login page loads but is blank, or the console shows frappe.boot is undefined.

Fix: Stale cached JavaScript files. Rebuild and clear:

bench build
bench --site yoursite.com clear-cache
bench --site yoursite.com clear-website-cache
sudo supervisorctl restart all

Tell users to hard-refresh their browsers (Ctrl+Shift+R).

Error 2: "Incorrect password" for Administrator

Fix: Reset the Administrator password from the command line:

bench --site yoursite.com set-admin-password [new-password]

Error 3: Two-factor authentication locked out

Symptom: The 2FA code is rejected and there is no backup code.

Fix: Disable 2FA for the user from the command line:

bench --site yoursite.com console
>>> frappe.db.set_value('User', 'user@example.com', 'two_factor_auth', 0)
>>> frappe.db.commit()

Error 4: "Your account has been locked"

Symptom: Too many failed login attempts triggered the account lockout.

Fix: Wait 60 minutes (default lockout period) or unlock from console:

bench --site yoursite.com console
>>> user = frappe.get_doc('User', 'user@example.com')
>>> user.unlock()
>>> frappe.db.commit()

Skimmable summary: blank login → bench build + clear-cache. Forgot admin password → bench set-admin-password. 2FA locked → disable via console. Account locked → unlock via console or wait 60 minutes.

How do I fix ERPNext permission errors?

Permission errors show up as "Not permitted" messages or as users unable to see documents they should have access to.

Understanding ERPNext permissions:

ERPNext uses a layered permission model: Role → DocType Permission → User Permission → Sharing. Each layer restricts further.

Fix 1: User cannot see a DocType at all

Go to Setup → Role Permission Manager. Find the DocType. Check that the user's role has at least "Read" permission. If the role is missing, add it.

Fix 2: User can see the DocType but not specific records

This is a User Permission issue. Go to Setup → User Permission → check if there is a restriction limiting which records the user can see. For example, a User Permission restricting "Company" to "Company A" means the user cannot see documents from "Company B".

Fix 3: User cannot create or submit documents

Check that the user's role has "Create" and "Submit" permissions in Role Permission Manager. Also check the workflow — if the document has an approval workflow, the user may need "Approve" permission on their specific workflow state.

Fix 4: "Cannot edit after submission"

Submitted documents in ERPNext are locked by design. To modify a submitted document, you must either:

  • Amend: Cancel the document and create an amended version (preferred for invoices, stock entries)
  • Enable "Allow on Submit" fields: In Customize Form, specific fields can be marked as editable after submission

Debugging tip: Log in as the affected user (Setup → User → click "Login As") to reproduce the exact permission error they see. This is faster than guessing which role or permission is wrong.

Skimmable summary: "Not permitted" → check Role Permission Manager for the DocType. Can see list but not records → check User Permissions. Cannot create/submit → check role's Create/Submit flags and workflow state permissions.

Frequently asked questions

How do I check which ERPNext version I am running?

Open ERPNext in your browser and click the help icon (?) in the top-right navbar, then click "About". This shows the Frappe Framework version, ERPNext version, and all installed apps with their versions. From the command line: bench version lists all app versions. For the full upgrade path between versions, see the v15 to v16 upgrade guide.

How do I restore ERPNext from a backup?

Run bench --site yoursite.com restore [path-to-sql-file]. For a complete restore including uploaded files: bench --site yoursite.com restore [sql-file] --with-private-files [private-files.tar] --with-public-files [public-files.tar]. Always test the restore on a separate site before overwriting production. Backups are stored in ~/frappe-bench/sites/yoursite.com/private/backups/.

How do I fix "Too many writes in a transaction" error?

This error appears when a single operation tries to modify more than 200 documents (the default limit). Common trigger: bulk operations via API or importing large datasets. Fix: break the operation into smaller batches, or temporarily increase the limit in site_config.json: "flags": {"in_import": true} (remove after the import completes).

Why is my ERPNext site slow after importing data?

Large data imports create many database entries without optimised indexing. After a bulk import, run bench --site yoursite.com migrate to ensure all indexes are created, then restart MariaDB to clear query cache: sudo systemctl restart mariadb. If the site is still slow, check that innodb_buffer_pool_size in MariaDB config is set to at least 50% of available RAM.

Print formats fetch CSS and images using the host_name from site_config.json. If host_name is wrong (e.g., set to localhost in production, or missing the HTTPS prefix), print formats render without styling. Fix: set host_name to your full site URL including protocol: "host_name": "https://erp.yourcompany.com".

How do I get professional help with ERPNext errors?

For complex errors (data corruption, failed migrations, performance tuning), an ERPNext implementation partner can diagnose and fix issues faster than forum troubleshooting. Mith Tech provides emergency support for production-down situations — typical resolution time is under 4 hours for critical errors.

ERPNext broken and need it fixed now?

I provide same-day ERPNext troubleshooting for production-critical errors — deadlocks, failed migrations, data corruption, and performance emergencies. Book a call and describe the error — most issues are resolved within 4 hours.

About the author

Manoj is the founder of Mith Tech, a Bengaluru-based consultancy specialising in ERPNext, Frappe, and open-source business infrastructure for SMEs across India and Southeast Asia. He has debugged and fixed ERPNext production issues for manufacturers, distributors, and service businesses since 2020 — from deadlocked databases to failed multi-version upgrades.