Your EA stops placing orders. The log is full of red text. You think the code is broken.
Before you panic: in our experience, the vast majority of EA errors have simple, fixed solutions. Usually it's not the code. It's a broker setting change, a permission switch, or a lot size calculation issue. You don't need to know MQL programming to diagnose most of these. You just need to know which error code means what.
This article covers the four most common errors in detail, then provides a complete reference table for everything else.
The four errors you'll hit most often
Based on what we see in FXTool support tickets, these four come up far more than anything else.
Error 130: Invalid stops
We see Error 130 in our support tickets more than any other code — it's almost always a stop distance issue, not a bug in the EA.
Your stop loss or take profit is too close to the current price. Every broker sets a minimum stop distance (Stop Level) per instrument. If your EA sets a 15-pip stop loss but the broker requires a minimum of 20 pips, the order gets rejected.
How to check: in MT4, right-click the symbol → Specifications → look for "Stops level." In MT5, it's under the Trading tab.
Fix: in the EA code, use MarketInfo(Symbol(), MODE_STOPLEVEL) to get the minimum distance before placing orders (see MQL5 OrderSend documentation for full parameter details). Set stops at least 5 pips beyond this minimum to provide buffer. Note that some brokers temporarily increase Stop Level during high volatility (around NFP, rate decisions).
Another common cause: the EA calculates stops in 4-digit pips but the broker uses 5-digit pricing. The stop is 10x too tight. Verify whether your EA uses pips or points, and check it against the broker's quote format.
Error 131: Invalid trade volume
The lot size is illegal. Three possible causes: lot is below the broker's minimum (trying 0.03 when minimum is 0.1), lot exceeds the maximum, or lot doesn't align with the step size (trying 0.07 when step is 0.05).
Fix: check three MarketInfo values: MODE_MINLOT, MODE_MAXLOT, MODE_LOTSTEP. Normalize the calculated lot size to the nearest valid step before sending the order. This is a one-time code fix that prevents the error permanently.
Error 138: Requote
The price changed between when the EA sent the order and when the server tried to execute it. Common during fast markets, especially around data releases.
Fix: add retry logic. If the order fails, refresh rates and try again:
int retries = 3;
while(retries > 0) {
RefreshRates();
ticket = OrderSend(...);
if(ticket > 0) break;
retries--;
Sleep(500);
}
Also increase the slippage parameter in OrderSend. Default of 3 points on a 5-digit broker means you're only accepting 0.3 pips of slippage, which is unrealistic during volatility. Set it to 10–20 for practical execution. In our own EAs, we default slippage to 15 points and haven't had a requote issue since.
Error 146: Trade context busy
MT4 processes trading operations single-threaded. If you run multiple EAs and one is mid-order, the others get Error 146 because the trading thread is occupied.
Fix: check IsTradeAllowed() before placing orders. If it returns false, wait and retry:
int wait = 0;
while(!IsTradeAllowed() && wait < 20) {
Sleep(500);
wait++;
}
This issue doesn't exist in MT5 because MT5 supports multi-threaded trading. When we migrated our own EAs from MT4 to MT5, Error 146 disappeared completely — it's one of the strongest practical reasons to make the switch. If you frequently run multiple EAs and hit Error 146, migrating to MT5 eliminates the problem entirely.
Error 4109: trade not allowed
Almost always a setup issue, not a code issue. Check three switches:
- The "Algo Trading" button on the MT4/MT5 toolbar. Must be green.
- EA properties → Common tab → "Allow Algo Trading" checkbox. Must be checked.
- Tools → Options → Expert Advisors → "Allow Algo Trading." Must be checked.
All three must be on. Missing any one silently blocks all trades. These settings can reset after MT4 updates or when installing on a new VPS.
When OrderSend returns -1
OrderSend returning -1 means the order failed. Call GetLastError() immediately after to get the specific error code. Don't insert any other function calls between OrderSend and GetLastError(), or the error code gets overwritten.
Standard pattern:
int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 10, sl, tp);
if(ticket < 0) {
int err = GetLastError();
Print("OrderSend failed. Error: ", err);
}
Complete error code reference
For the full official list, see the MQL5 error codes reference. Below are the codes you'll encounter most often in practice.
Server errors (0–150)
| Code | Name | Meaning | Fix |
|---|---|---|---|
| 0 | No error | Success | — |
| 2 | Common error | General failure | Retry, check parameters |
| 4 | Server busy | Trade server overloaded | Wait a few seconds, retry |
| 6 | No connection | Disconnected from server | Check network, reconnect |
| 8 | Too frequent | Requests sent too fast | Add Sleep() between operations |
| 64 | Account disabled | Account locked | Contact broker |
| 128 | Trade timeout | No server response | Check network, retry |
| 129 | Invalid price | Wrong price used | Use current Ask/Bid, refresh rates |
| 130 | Invalid stops | Stop too close | Increase stop distance past Stop Level |
| 131 | Invalid volume | Illegal lot size | Normalize to min/max/step |
| 132 | Market closed | Non-trading hours | Wait for market open |
| 133 | Trade disabled | Symbol not tradable | Check with broker |
| 134 | Not enough money | Insufficient margin | Reduce lot size or deposit more |
| 135 | Price changed | Price moved | Refresh and retry |
| 136 | Off quotes | No quotes available | Wait for quotes to resume |
| 138 | Requote | Price moved during execution | Increase slippage or retry |
| 145 | Modification denied | Order too close to market | Wait for price to move away |
| 146 | Trade context busy | Another EA is trading | Wait with IsTradeAllowed() loop |
| 148 | Too many orders | Position/order limit reached | Close some positions |
MQL runtime errors (4000+)
| Code | Name | Fix |
|---|---|---|
| 4001 | Wrong function pointer | Check code logic |
| 4002 | Array index out of range | Verify array size before access |
| 4051 | Invalid function parameter | Check input ranges (no zero/negative periods) |
| 4055 | Custom indicator error | Verify indicator is installed correctly |
| 4106 | Unknown symbol | Check symbol spelling (EURUSD vs EURUSDm vs EURUSD.pro) |
| 4109 | Trade not allowed | Check three trading permission switches |
| 4110/4111 | Longs/shorts not allowed | Check account trading permissions with broker |
How to read the Experts and Journal tabs
Two tabs at the bottom of MT4 that most traders never open until something breaks.
The Experts tab shows EA output: Print() statements and error messages. Red text = errors (must investigate). Yellow = warnings. White/gray = normal log. Format: timestamp + EA name + symbol + message.
The Journal tab shows MT4 terminal operations: connection status, login events, order execution details. You can see actual fill prices, slippage amounts, and disconnection timestamps.
To diagnose a problem: note when it happened, check Experts for EA errors at that time, then check Journal for connection issues at the same time. Comparing both usually makes the cause obvious.
Right-click either tab → Open to jump to the log file folder. Log files are plain text, searchable with any text editor.
Debugging tips
Add Print() statements at key points. Before every OrderSend, print the price, lot size, stop loss, take profit, and current spread. When something fails, the log shows you exactly what values were used.
Check broker trading conditions when switching brokers or account types. Minimum lot, lot step, stop level, symbol name, and quote digits can all change. A good EA reads these dynamically from MarketInfo() rather than hard-coding them. If you're unsure what to look for in a backtest report, errors during testing are a sign the EA isn't adapting to broker specs.
Change one thing at a time when troubleshooting. Adjust one parameter, test, confirm the effect. Changing three things at once means you don't know which one fixed (or broke) it.
Build error handling into every trading operation. Every OrderSend, OrderModify, and OrderClose should check the return value and log failures. For retryable errors (138, 146), retry automatically. For fatal errors (134 insufficient margin), stop trading and send an alert via SendNotification() (Tools → Options → Notifications → configure your MetaQuotes ID).
For a full walkthrough of EA setup and parameter configuration, see our dedicated guides. Every EA in the FXTool marketplace includes error handling for all common error codes.
FAQ
My EA backtests fine but errors on live. Why?
Backtesting has no network delays, no requotes, and no trade context contention. Live trading has all three. The most common causes: live broker has stricter stop level than backtest assumed, live spreads are wider, or the symbol name doesn't match. Run on demo for a few days before going live to catch these issues.
Same EA works on one broker, errors on another. What changed?
Different brokers have different minimum lots, step sizes, stop levels, symbol names, and quote digits — this is one reason choosing the right broker matters. A well-built EA reads these dynamically using MarketInfo(). If yours uses hard-coded values, you'll need to adjust them for each broker.
What does "OrderSend Error 0" mean?
Error 0 means "no error," but OrderSend returned -1 anyway. This happens when GetLastError() was called at the wrong time. Something between the failed OrderSend and GetLastError() reset the error code. Fix: call GetLastError() immediately after OrderSend, with no other operations in between.
Are MT4 and MT5 error codes the same?
Server errors (0–150) are mostly identical. MQL runtime errors (4000+ range) are significantly different in MT5. MT5 uses a new error code system, and function signatures like OrderSend() have changed. If migrating from MT4 to MT5, error handling needs to be rewritten.
About the author: The FXTool team builds and tests MetaTrader trading tools daily. We run every EA we sell on live accounts and publish the results. This guide reflects what we've learned from building 50+ EAs and working with thousands of retail traders.
Forex trading involves significant risk and may result in total loss of capital. This article is for educational purposes only and is not investment advice. Understand the risks and consider your financial situation before trading.