The halting problem asks whether it is possible to write a program that can examine any other program, together with its input, and reliably decide whether that program will eventually finish or run forever. In 1936 Alan Turing proved that no such program can exist. This is not a statement about present-day technology or about how clever programmers are. It is a mathematical proof that the task is impossible, and it will remain impossible however fast computers become.
Turing showed that the assumption that a general halting detector exists leads to a contradiction. Suppose a program H could take any program and input and correctly answer "halts" or "runs forever". One could then build a second program that calls H on itself and deliberately does the opposite of whatever H predicts: if H says it halts, it loops forever, and if H says it loops forever, it halts immediately. That program's behaviour is now something H cannot correctly report, so H cannot have existed in the first place.
The argument is a diagonalisation, the same style of reasoning Georg Cantor used to show that some infinities are larger than others, and that Kurt Godel used in his incompleteness theorems a few years earlier.

The halting problem is the first and most famous of a family of undecidable problems, and its consequences are practical rather than merely philosophical. By a later result known as Rice's theorem, essentially every interesting question about what a program does, rather than about the text of the program itself, is also undecidable in general. No tool can perfectly determine whether arbitrary code contains an infinite loop, whether it will ever crash, or whether it is a virus.
This is why static analysers, type checkers, and security scanners are all necessarily incomplete. They give up either completeness, by missing some real problems, or soundness, by reporting problems that are not there, because the alternative is provably unavailable.

The result is often overstated. It does not say that halting can never be determined for any program: for enormous numbers of specific programs the answer is obvious, and automated tools prove termination for real code every day. What is impossible is a single general method guaranteed to work for every possible program. The undecidability is about universality, not about difficulty in particular cases.