Search

The Two Generals Problem: Why Perfect Communication Is Impossible

The short answer

Quick answer: The Two Generals' Problem is a thought experiment showing that two parties cannot reach guaranteed agreement if the only way they can communicate is a channel that may lose messages. Whatever the last message is, its sender cannot know whether it arrived, so one side is always uncertain. Adding more acknowledgements never fixes it. This is a proven impossibility, not an engineering gap. Real systems cope by accepting a small remaining uncertainty and using retries, timeouts and idempotent operations so that the uncertainty does no harm.

The story

Two armies are camped on hills either side of a valley. In the valley is a fortified city. The two generals can capture it only if they attack at the same time; a lone attack will be defeated.

They can communicate only by sending messengers through the valley, where any messenger may be captured. A captured messenger simply never arrives.

General A sends: "Attack at dawn."

Should A attack at dawn? Not yet. A does not know whether the message got through. If it did not, A would be attacking alone.

So General B sends back: "Received. I will attack at dawn."

Should B attack? B does not know whether that confirmation got through. If it did not, A will not attack, and B would be attacking alone.

So A confirms the confirmation. But now A does not know whether that arrived, and B, not having received it for certain, cannot be sure A is confident.

Each new message just moves the doubt to the other side.

Why no protocol can work

Here is the argument, in outline.

  1. Suppose some protocol exists that guarantees both generals attack together, using a finite number of messages.
  2. Take a run of that protocol where every message is delivered, and consider the last message.
  3. Its sender must already be committed to attacking before knowing whether it arrived, since no further message will tell them. So the protocol must also work if that last message is lost.
  4. In that case, the last message was unnecessary. Remove it, and you have a shorter protocol that still works.
  5. Repeat. You end up with a protocol that sends no messages at all, which obviously cannot coordinate anything.

That is a contradiction, so no such protocol exists.

The Two Generals' Problem was first described in the 1970s and later given its name by Jim Gray. It is often cited as the first computer communication problem proved to be unsolvable.

What the generals need is common knowledge: A knows, B knows that A knows, A knows that B knows that A knows, and so on without end. An unreliable channel can add layers to that chain but can never complete it.

Where you meet it in real life

The lost response

You tap "Pay". The request goes to the server. No response comes back.

Did the server never receive it, or did it process the payment and the reply got lost? From your side these are indistinguishable. This is exactly the generals' dilemma, and it applies to every request over a network. It is the root of the "partial failure" problem described in why distributed systems are hard.

TCP connections

TCP opens a connection with a three-way handshake: SYN, SYN-ACK, ACK. The side that sends the final ACK does not know whether it arrived. TCP accepts this. If the ACK is lost, the other side retransmits its SYN-ACK, and things recover.

Closing a connection has the same shape. After the final acknowledgement, the closer waits a while in case it needs to resend. There is no moment at which both sides are certain the other knows the connection is closed.

"Exactly once" delivery

A message system can retry until it gets an acknowledgement (messages may arrive twice) or not retry (messages may be lost). It cannot guarantee delivery exactly once, because the sender can never be sure whether the receiver got a message whose acknowledgement went missing. See how message queues work.

Distributed transactions

Two-phase commit asks every participant to vote and then tells them the decision. If the coordinator fails after participants have voted "yes" but before they hear the outcome, they are stuck: they cannot safely commit or abort on their own.

How real systems live with it

The impossibility result says you cannot be certain. It does not say you cannot be reliable enough, or that uncertainty must be harmful.

1. Make certainty unnecessary

If repeating an action is harmless, you no longer need to know whether the first attempt succeeded. Just try again.

at-least-once delivery  +  idempotent handling  =  the effect happens once

A payment request carries a unique key. If the client retries after a timeout, the server recognises the key and returns the original result without charging again. This is the single most important practical answer to the Two Generals' Problem; see how payment systems avoid charging you twice.

2. Retry until acknowledged

Send, wait, resend. TCP does it. Queues do it. With each retry the chance that nothing ever got through shrinks towards zero, though never exactly to it. Use exponential backoff so retries do not overwhelm a struggling server.

3. Use timeouts and move on

Decide how long you will wait, then act on your best guess, and design the system so a wrong guess can be corrected later.

4. Check afterwards

Where it matters, reconcile. Banks compare their ledgers with each other at the end of the day. A client that timed out can query "what is the status of request X?" before deciding to retry.

5. Use a majority

With more than two parties, consensus algorithms such as Raft reach agreement as long as a majority can communicate. They do not escape the impossibility; they guarantee never to give a wrong answer, and they make progress whenever the network behaves well enough.

Not the Byzantine Generals

The two problems are often confused.

Two GeneralsByzantine Generals
Number of partiesTwoMany
What goes wrongThe channel loses messagesSome participants lie or act maliciously
ParticipantsHonestPossibly traitors
Solvable?No, not with certaintyYes, if fewer than a third are faulty
RelevanceEvery networked systemBlockchains, aerospace, hostile environments

The Byzantine generals problem is about untrustworthy participants. The Two Generals' Problem is about an untrustworthy channel between trustworthy ones.

Why it matters to working programmers

The lesson fits in one sentence: a timeout does not mean failure. When a remote call times out, the operation may or may not have happened, and you cannot find out by waiting.

So, for any operation that changes something:

  • Assume it may be executed more than once.
  • Give it an identity, so duplicates can be detected.
  • Make the handler idempotent.
  • Provide a way to look up what actually happened.

Frequently asked questions

What is the Two Generals' Problem in simple terms?

Two parties need to agree on a plan but can only talk over a link that may drop messages. Neither can ever be fully sure the other received the latest message, so guaranteed agreement is impossible.

Is the Two Generals' Problem solvable?

No. It has been proved that no protocol can guarantee agreement over an unreliable channel. Practical systems reduce the uncertainty and make it harmless.

How does TCP work if the problem is unsolvable?

TCP does not achieve certainty. It uses acknowledgements, retransmission and timeouts to make communication reliable in practice, and tolerates the small remaining ambiguity.

What is the difference between the Two Generals and Byzantine Generals problems?

The first is about messages being lost between honest parties. The second is about reaching agreement when some participants may be dishonest.

Conclusion

The Two Generals' Problem is a small story with a large consequence: over an unreliable network, you can never be completely sure the other side got your message. Every reliable system is built with that fact in mind. They do not defeat the uncertainty. They retry, deduplicate and reconcile until it stops mattering.

Related articles

Sources and further reading

Usama Muneer

Usama Muneer

Coder, Blogger, Tech Speaker & Web Technologies Enthusiast. Passionate about working on open-source Programming languages & Tools while utilizing my Product Development skills.

Your experience on this site will be improved by allowing cookies Cookie Policy