MS_MAX_CONCURRENT_REQ: what it means and how to handle itYou call VIES to check an EU VAT number and get a SOAP fault instead of an answer. Here is what the error actually says, and how to handle it in production.
MS_MAX_CONCURRENT_REQ means the member state you are querying has reached its maximum number of concurrent requests. VIES is only a router: each country runs its own back end, and each one caps how many requests it accepts at once, for everybody, across the whole EU.
So the limit is not about you. Your code can be perfectly well behaved and still hit it, because thousands of other businesses are checking German or Italian numbers at the same moment. It is common during office hours and at month end, when invoicing peaks.
| Fault | Meaning | Retry? |
|---|---|---|
MS_MAX_CONCURRENT_REQ | One member state is saturated. | Yes, later |
GLOBAL_MAX_CONCURRENT_REQ | VIES as a whole is saturated. | Yes, later |
MS_UNAVAILABLE | The member state's system is down (maintenance windows are frequent at night and on weekends). | Yes, later |
SERVICE_UNAVAILABLE, TIMEOUT | VIES itself did not answer in time. | Yes |
INVALID_INPUT | Unknown country code or malformed number. | No, fix the input |
IP_BLOCKED | Your IP was blocked for excessive traffic. | No, slow down first |
The tempting fix is a tight retry loop. It makes things worse: you add load to a country that is already saturated, and aggressive clients can end up with IP_BLOCKED, which hurts every validation you make, not only the busy country.
import time
RETRYABLE = {"MS_MAX_CONCURRENT_REQ", "GLOBAL_MAX_CONCURRENT_REQ",
"MS_UNAVAILABLE", "SERVICE_UNAVAILABLE", "TIMEOUT"}
def check_with_backoff(check, country, number, delays=(5, 30, 120)):
for delay in (0, *delays):
time.sleep(delay)
try:
return check(country, number)
except ViesFault as e: # your own exception carrying the fault string
if e.code not in RETRYABLE:
raise
raise RuntimeError(f"VIES still unavailable for {country}")
Skip the plumbing. Vatline wraps VIES in a REST/JSON API with caching, retry hints and per-country circuit breakers. Free plan: 300 checks a month, no card. Read the docs or try a number now.