upstream_unavailable
HTTP Status: 503 Service Unavailable
Example response
vat_number you submitted (and requester_vat_number when supplied), so your logs always record which number the failed attempt was for. meta.validation_id identifies the attempt in Avatcado’s records; include it when contacting support.
What happened?
The upstream VAT validation service could not be reached, or it returned an unexpected error. This happens when:- VIES (EU), HMRC (UK), BFS UID Register (CH/LI), Bronnoysund Register Centre (NO), or ABR (AU) is down for maintenance
- A network timeout occurred while connecting to the upstream service
- The upstream service returned an unexpected HTTP error status
- An unexpected exception occurred during the validation request
- DNS resolution failed for the upstream service
How to fix
- Retry after the
Retry-Afterheader: The response includesRetry-After: 10, telling you to wait 10 seconds before retrying. Then use exponential backoff, doubling each time up to a maximum of 60 seconds - Check upstream service status:
- VIES: https://ec.europa.eu/taxation_customs/vies/
- HMRC: https://api-platform-status.production.tax.service.gov.uk/
- BFS UID Register (CH/LI): https://www.uid.admin.ch/
- Bronnoysund Register Centre (NO): https://www.brreg.no/
- ABR (AU): https://abr.business.gov.au/
- Handle gracefully: Show users a message like “VAT validation is temporarily unavailable, please try again later”
Common mistakes
- No retry logic: Always implement retries for 503 errors since they’re transient by nature
- Retrying too aggressively: Use exponential backoff, not a tight loop
- Blaming Avatcado: This error means the third-party service (VIES, HMRC, BFS, Bronnoysund, or ABR) is having issues, not the Avatcado API itself
Catching this error with the SDKs
Billing
This error is not counted against your monthly quota. When the upstream is unavailable and no cached or stale fallback can be served, the API automatically refunds the request so you are not charged for an unanswered call. See Non-billable failures. If a stale fallback was served instead (HTTP200 with meta.stale: true), the request does count, since you received usable data. The same is true for a national registry fallback (HTTP 200 with meta.source_status: "fallback"): the request counts, since data was served.
Stale cache fallback
If Avatcado has a previous cached result for the same VAT number, it will serve that result withmeta.stale: true instead of returning a 503 error. See Caching for details.
A request that carries requester_vat_number is the exception: it never serves a stored result (a consultation number has to come from the check that produced the answer), so it gets this error, refunded, whenever the upstream is down. Pass cache=true to accept the stored result instead; see Consultation numbers.
Member state unavailability
When a specific VIES member state is down (rather than the entire VIES service), Avatcado detects this via the VIESuserError field. On Pro and Business plans, for BE (companies only), CZ, EE, FI, FR, HR, LV, RO, SI, and SK, it first consults that country’s national tax register and serves the answer with meta.source_status: "fallback" when the register confirms the number (unless the request passed fallback=false, or carries requester_vat_number without fallback=true). Otherwise, on the Free plan, or if the national register fails or does not confirm the number, it falls back to the most recent stored result with meta.source_status: "unavailable" instead of returning a 503 error. If no stored result exists either, a 503 error with code upstream_member_state_unavailable is returned instead.
On the Free plan, when the country has a national register and nothing is stored, the message of that error, and of this one when VIES itself timed out or refused the connection, ends with National register fallback (10 EU countries) is available on Pro and Business plans. On Pro and Business the same position carries The national register was not consulted because requester_vat_number was supplied. Pass fallback=true to accept a register answer, which never carries a consultation_number. when the request carried a requester without fallback=true. The code and the refund are unchanged; only the message grows.