Canonical SAN is not produced by spelling out every fact about a move.
It produces the shortest canonical description that still identifies the legal move unambiguously, then appends the required capture, promotion, and check/mate information.
The most important word is:
legal.
PGN SAN ambiguity is determined among pieces of the same type that can legally move to the same destination.
SAN disambiguates legal moves, not merely geometric attacks.
Anatomy of a SAN move
A useful construction template is:
piece → disambiguation → capture → destination → promotion → check/mate
Not every move uses every component.
Examples:
Nf3;Bxc6;Nce2;R1e2;Qh7#;fxg8=Q+.
Pawn exception
For pawns:
- no piece letter;
- capture includes origin file.
Examples:
e4;exd5;e8=Q;fxg8=N+.
Construction order
For a non-castling move:
- Identify moving piece type.
- Determine all legal same-type movers to the destination.
- Add disambiguation if required.
- Add
xif capture. - Add destination square.
- Add
=Pieceif promotion. - Add
+or#from the resulting position.
Determine legality before determining SAN ambiguity.
When disambiguation is needed
Suppose two White knights can both legally move to e2:
- knight c3;
- knight g1.
Writing:
Ne2
would not uniquely identify the mover.
Because their origin files differ:
- c-file;
- g-file;
use file disambiguation:
Nce2;Nge2.
This example appears in the PGN specification itself.
Disambiguation priority
The PGN rule uses the first sufficient method in this order:
- origin file;
- origin rank if file is insufficient;
- full origin square if both are required.
| Situation | SAN disambiguator |
|---|---|
| Origin files distinguish movers | file letter |
| Files do not distinguish, ranks do | rank digit |
| Neither file nor rank alone distinguishes | full origin square |
File first. Rank second. Full origin only when necessary.
Do not use more origin information than canonical SAN requires.
File disambiguation
Example position:
- White knight c3;
- White knight g1;
- both legally move e2.
Moves:
Nce2;Nge2.
The destination remains:
- e2.
The inserted origin file answers:
Which knight?
Captures
If the destination contains a capturable enemy piece:
Ncxe2would placexafter the disambiguator if the c-file knight captures there.
Rank disambiguation
Rank is used only when:
- multiple legal same-type movers share the same origin file;
- rank distinguishes them.
Example construction pattern:
- two rooks on same file;
- both can legally reach the same destination after verified geometry.
Possible forms:
R1e2;R4e2.
The exact examples must be verified from legal positions.
Full-origin-square disambiguation
This is rare.
It is needed when:
- file alone fails;
- rank alone also fails.
That requires at least three same-type pieces or a promoted-material configuration capable of producing overlapping legal destinations.
Canonical form:
piece letter + full origin square + destination
or with capture:
piece letter + full origin square + x + destination.
Example template:
Qa1e5;Qa1xe5;
only when a legality-verified position genuinely requires full-square disambiguation.
Do not invent full-origin SAN examples casually.
They are easy to make non-canonical because:
- file may already be sufficient;
- rank may already be sufficient;
- one geometric candidate may be illegal.
Legality and disambiguation
This is one of the most important rules in the entire domain.
PGN does not disambiguate among pieces that merely attack the destination.
It disambiguates among pieces of the same type that can legally move there.
Canonical pinned-knight example
White:
- king e1;
- knight c3;
- knight g1.
Black:
- bishop b4.
Destination:
- e2.
Geometrically:
- both knights attack e2.
But the c3 knight is absolutely pinned if moving exposes the White king along the bishop line.
Therefore only the g1 knight can legally move e2.
SAN:
Ne2.
Not:
Nge2.
A pinned geometric candidate does not create SAN ambiguity when its move is illegal.
The key distinction is:
- geometric reach or attack map ≠ legal move map.
Capture with disambiguation
Disambiguation comes before x.
General shape:
Piece + disambiguator + x + destination
Examples after verified construction:
Raxd1;R1xd4;N5xf4where rank disambiguation is genuinely required.
The disambiguator identifies the mover. `x` describes the move as a capture.
Check/mate does not remove ambiguity
Suppose two legal rooks can move to e8.
If one move gives check and another does not, that checking difference does not replace SAN disambiguation.
The mover still must be identified according to:
- file;
- rank;
- full origin.
PGN explicitly states that check/mate indications do not alleviate ambiguity.
Promotion + capture + check/mate
Promotion SAN can combine several components.
Non-capture promotion
e8=Q.
Promotion with check
e8=Q+.
Capture promotion
fxg8=Q.
Capture promotion with check
fxg8=Q+.
Underpromotion mate
exd8=N#
if the verified position produces that result.
The sequence is:
pawn origin file → x → destination → =promotion → +/#
g8SAN components have an order. Do not rearrange them freely.
Castling is exceptional syntax
Castling does not use:
K;- destination square;
- rook notation.
Canonical PGN SAN uses:
O-O;O-O-O.
Then append:
+;#
when applicable.
Examples:
O-O+;O-O-O#.
SAN construction practice
For every exercise:
- show a legality-verified position;
- identify the move in plain language;
- construct canonical SAN.
Family A — simple
- pawn quiet move;
- knight quiet move;
- bishop capture.
Family B — state suffix
- checking move;
- mating move.
Family C — special
- castling;
- promotion;
- en passant.
Family D — ambiguity
- file disambiguation;
- rank disambiguation;
- full-origin disambiguation.
Family E — complex
- disambiguated capture + check;
- promotion capture + check;
- underpromotion mate.
SAN decoding practice
Decoding reverses construction.
Given:
Raxd1+
Ask:
- moving piece?
- origin clue?
- capture?
- destination?
- resulting state?
Answer:
- rook;
- origin a-file;
- capture;
- d1;
- check.
Example: fxg8=N+
Decode:
- pawn from f-file;
- captures on g8;
- promotes to knight;
- gives check.
Example: Nce2
Decode:
- knight;
- originating c-file;
- destination e2;
- no capture;
- no check/mate suffix.
SAN does not always reveal the exact origin square.
You may need the current position to reconstruct it.
Malformed vs impossible SAN
Two different problems exist.
Syntactically malformed
Example:
- wrong component order;
- impossible token pattern.
Positionally impossible
The string looks SAN-like, but no legal move in the given position matches it.
Example:
Nf3when no legal knight can reach f3.
SAN validity is position-dependent, not purely string-dependent.
The disambiguation decision tree
Disambiguation is easier when treated as a legal-move filtering problem rather than a typography rule.
For the piece that actually moved:
- Find every same-type, same-colour piece that could legally move to the same destination.
- Ignore pieces whose geometric route exists but whose move is illegal, for example because moving them would expose their own king.
- If only one legal mover remains, no origin clue is needed.
- If several remain, compare their origin files.
- If the files distinguish them, include the file.
- Otherwise compare ranks and include the rank.
- If neither file nor rank alone is enough, include the full origin square.
This is why SAN disambiguation cannot be generated correctly from geometry alone. It requires a legal move generator or equivalent reasoning about king safety.
Why SAN uses the minimum sufficient origin information
SAN does not normally spell out an entire move like Ng1f3. Its design is economical: include only enough information to identify the legal mover.
Suppose two rooks can legally move to e1:
- one starts on a1;
- one starts on h1.
Their files differ, so Rae1 and Rhe1 are sufficient. Writing Ra1e1 would be a longer coordinate-style description, not the minimal SAN form.
Now suppose two rooks are on a1 and a5 and both can legally reach a3. Their file is the same, so the rank is what distinguishes them: R1a3 or R5a3.
Full-square disambiguation is rare because it requires a configuration in which neither file nor rank alone uniquely identifies the mover.
SAN generation vs SAN parsing
These are related but different tasks.
Generating SAN starts from a known legal move and asks how to write it canonically.
Parsing SAN starts from a token and a position and asks which legal move the token identifies.
A robust parser therefore needs to understand:
- piece type;
- optional origin clue;
- capture state;
- destination;
- promotion;
- check/mate suffix;
- the current legal move set.
String pattern matching alone is not enough to prove that a SAN token represents a legal move.
Frequently asked questions
Do pinned pieces count for SAN disambiguation?
Only if they have a legal move to the destination. A piece that is geometrically able to reach the square but cannot legally move because its king would be left in check does not create SAN ambiguity.
Can check or mate distinguish two candidate movers?
No. If two legal same-type pieces can reach the destination, SAN still uses the normal origin disambiguation rules. A + or # suffix describes the resulting position; it is not a substitute for identifying the mover.
Why does SAN sometimes contain a file and sometimes a rank?
The goal is minimum sufficient identification. File is preferred when it distinguishes the legal candidates; rank is used when file does not; full origin square is the fallback when necessary.
Key takeaways
Canonical SAN construction:
- find the legal move;
- identify whether same-type legal ambiguity exists;
- disambiguate by:
- file;
- then rank;
- then full origin square;
- add capture;
- destination;
- promotion;
- check/mate.
Critical safeguards:
- illegal/pinned candidates do not force disambiguation;
- check/mate difference does not remove ambiguity;
- disambiguator comes before
x; - promotion component follows destination;
- SAN must be interpreted against a position.
Check your understanding
- [ ] I know SAN component order.
- [ ] I know when ambiguity exists.
- [ ] I use file before rank.
- [ ] I know full origin is rare.
- [ ] I ignore illegal candidates for disambiguation.
- [ ] I can build disambiguated captures.
- [ ] I can build promotion/capture/check combinations.
- [ ] I can decode SAN components.
- [ ] I distinguish malformed syntax from impossible-in-position SAN.