Vatline

VIES MS_MAX_CONCURRENT_REQ: what it means and how to handle it

You 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.

What the error means

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.

The related faults

FaultMeaningRetry?
MS_MAX_CONCURRENT_REQOne member state is saturated.Yes, later
GLOBAL_MAX_CONCURRENT_REQVIES as a whole is saturated.Yes, later
MS_UNAVAILABLEThe member state's system is down (maintenance windows are frequent at night and on weekends).Yes, later
SERVICE_UNAVAILABLE, TIMEOUTVIES itself did not answer in time.Yes
INVALID_INPUTUnknown country code or malformed number.No, fix the input
IP_BLOCKEDYour IP was blocked for excessive traffic.No, slow down first

What not to do

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.

A strategy that works

  1. Validate the format locally first. A large share of failed lookups are typos. Each country has a fixed structure and some have a check digit (see VAT number formats). Reject those without calling VIES.
  2. Cache answers. A valid number does not become invalid during the day. Caching valid answers for 24 hours and invalid ones for a few minutes removes most repeat calls.
  3. Back off exponentially on retryable faults, for example 5 s, 30 s, then 2 minutes, and give up after that.
  4. Stop calling a country that keeps failing (a circuit breaker) for a minute or two, instead of every request discovering the outage on its own.
  5. Do not block the user. At checkout, accept the order and re-validate in the background rather than refusing a sale because a tax system is busy.

Minimal Python retry

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.