TL;DR: Military addresses use APO, FPO or DPO in place of a city and AA, AE or
AP in place of a state, and they are domestic US mail regardless of where in the world they
physically are. Detect them early, keep them out of rooftop accuracy metrics, and never send
them to a commercial carrier that cannot deliver to them. The wider family is covered in
handling PO boxes and rural routes.
The Markers Are in the City and State Fields
A military address does not look unusual in its delivery line. What identifies it is the pair of fields that would normally hold a city and a state, and recognising that pair is the whole detection problem.
That last line explains most of the confusion these addresses cause. A checkout form that infers an international shipment from the recipient’s actual location will price and route the order wrongly; the address is US domestic mail, handed to the military postal system at a US facility.
The Detector
from __future__ import annotations
import re
MILITARY_CITY = frozenset({"APO", "FPO", "DPO"})
MILITARY_STATE = frozenset({"AA", "AE", "AP"})
DELIVERY_RE = re.compile(
r"""
^(?:
(?:UNIT|PSC|CMR)\s+\d+ (?:\s+BOX\s+\d+)? # UNIT 2050 BOX 4190
| BOX\s+\d+ # BOX 4190
| (?:USS|USNS|USCGC)\s+[A-Z][A-Z\s]+ # USS THEODORE ROOSEVELT
)$
""",
re.IGNORECASE | re.VERBOSE,
)
def is_military(city: str | None, state: str | None) -> bool:
"""True when the city/state pair identifies a military or diplomatic address."""
return (
(city or "").strip().upper() in MILITARY_CITY
and (state or "").strip().upper() in MILITARY_STATE
)
def valid_military_delivery(line: str) -> bool:
"""True when the delivery line matches a recognised military format."""
return DELIVERY_RE.match(" ".join(line.split()).upper()) is not None
Requiring both markers is deliberate. AE alone appears in international data as a
country code for the United Arab Emirates, and APO alone occurs as a genuine place name;
only the pair is unambiguous.
What Not to Do With Them
The third rule is the one with a customer-facing consequence. Offering an expedited courier option on a military address and then discovering at dispatch that the carrier will not accept it produces a cancelled order and a support ticket, both avoidable by checking the address type at the point the options are presented.
Format Variants Worth Accepting
| Form | Example | Notes |
|---|---|---|
| unit and box | UNIT 2050 BOX 4190 |
the most common army and air force form |
| PSC and box | PSC 802 BOX 74 |
postal service centre, common in Europe |
| CMR and box | CMR 468 BOX 1234 |
community mail room |
| box alone | BOX 4190 |
valid where the unit is implied by the ZIP |
| ship designation | USS THEODORE ROOSEVELT |
fleet addresses name the vessel |
The ship form is the one most likely to be rejected by a validator written for the others, because it contains no digits at all. It is legitimate and common in FPO traffic, and a pattern that requires a numeric component will send a meaningful share of naval mail to a review queue.
Where the Rules Come From
Military addressing is defined by the postal service rather than by any individual carrier, and the format requirements are stricter than for ordinary domestic mail: the recipient’s full name and unit must both be present, and personal titles or foreign place names are explicitly discouraged because they can misroute the item once it enters the military system.
Those requirements matter for a validation pipeline because they cannot be checked mechanically. A record can be perfectly well-formed and still undeliverable because the recipient’s unit was omitted, and no address validator will report it. The practical response is to require a recipient name on military records specifically, and to surface a short format hint at the point of entry rather than a generic error afterwards.
The ZIP codes themselves are ordinary five-digit codes in dedicated ranges, so the postal code field needs no special handling — which is convenient, and occasionally misleading, because it makes the record look routine to any check that only inspects the postcode.
The Detection Decision, Drawn
Edge Cases and Failure Modes
A real city named after a military marker. Rare but present in gazetteers; requiring the state marker as well removes the ambiguity entirely.
Address validators that reject them. Some services handle military addresses poorly and return a failure rather than a special-type code. Detect the type before validation and either skip the call or interpret the failure accordingly.
Rooftop coordinates assigned by a geocoder. Several providers will happily return a coordinate for the handling facility. Suppress it deliberately rather than storing a coordinate that implies a precision the address does not have.
International shipping logic triggered by region. An AE record is not a European
shipment. Base the shipping decision on the country field, which says US, rather than on the
region code.
Presenting Them at the Point of Entry
Most of the operational trouble with these addresses is avoidable at the form rather than in the pipeline, and two small changes remove almost all of it.
The first is offering the markers as choices rather than expecting free text. A city field
that accepts APO, FPO and DPO from a list, and a state field that offers AA, AE and
AP alongside the ordinary states, produces clean records without the customer having to
know the convention. It also removes the most common failure mode entirely, which is a
recipient writing a foreign city name that the military postal system cannot route.
The second is deciding the shipping options after the address is known rather than before. Presenting an expedited courier option and withdrawing it at checkout is a poor experience; determining the address type first and offering only deliverable services avoids the retraction.
Both changes are small and both belong to the team that owns the form rather than the one that owns the pipeline, which is why the classification needs to be available early enough to inform them. Running the detector at entry rather than in the nightly batch is what makes that possible, and the detector is cheap enough that there is no reason not to.
Integration Note
Detection belongs in the same classifier that identifies the other non-street families in
handling PO boxes and rural routes,
and the resulting label feeds the same two consumers: the routing decision that sends box
records to a centroid lookup rather than a provider, and the accuracy reporting that
excludes them from rooftop metrics. The F1 footnote described in
understanding USPS DPV footnote codes
is the validator’s own confirmation of the same classification, and agreeing with it is a
useful cross-check on the local detector.
Running it at entry also means the customer sees the right guidance while they are still looking at the form, which is the only moment at which a format hint is genuinely useful.
A Note on Volume
These addresses are a small share of most consumer files and a much larger share of some, and knowing which case you are in changes how much effort the handling deserves.
For a general retailer they are typically well under one percent of orders, which is small enough that the review-queue path would be affordable and large enough that the failures are noticed. For a business selling to service members, families or government contractors the share can be several percent, and at that level every rule on this page pays for itself within a quarter.
Measuring the share is a single query against the city and state fields, and it is worth running before deciding how much of this to build. A pipeline that classifies them and does nothing else is already most of the value, because it prevents the two expensive failures — a rooftop coordinate that misleads, and a carrier option that cannot be fulfilled.
Related
- Handling PO Boxes and Rural Routes — the wider family of non-street delivery forms.
- Understanding USPS DPV Footnote Codes — the
F1code that confirms this classification. - Python Script to Extract PO Box Numbers — the box-number extractor these formats share.