"Bug" is one of the most-used and least-defined words in software. To make decisions about which bugs to fix, in what order, with what urgency, you need a precise definition. The good news: there is a clean one. The bad news: most teams never write it down, and disagreements about what is and isn't a bug eat hours every release.
A working definition
A bug is any deviation between the system's actual behaviour and what was expected. The "expected" side is the key — without an explicit expectation, there is no bug, only an opinion. Three sources commonly establish expectation:
- Specification. A written requirement, user story, design doc, or API contract.
- User intent. What a reasonable user would expect to happen.
- Implicit standards. Industry norms, accessibility requirements, security baselines, brand consistency.
If actual behaviour matches all three, the system is working as intended. If it deviates from any one of them, there is an argument for calling it a bug — and the argument is what the triage process exists to resolve.
Expected vs actual: the two-line bug report
Expected vs actual behaviour
Expected
Login form accepts valid credentials
Dashboard loads within 2 seconds
User sees a success notification
Order appears in order history
Actual (the bug)
Login form shows a blank page
Dashboard takes 15 seconds to load
No notification appears
Order is missing from history
The cleanest way to communicate a bug is the simple two-line frame:
- Expected: What should happen.
- Actual: What does happen.
Everything else in a bug report — repro steps, evidence, environment — supports those two lines. If you cannot fill in both, you do not yet have a bug; you have a question, a suggestion, or an observation. Treat them differently: a question gets asked, a suggestion gets put in the backlog, an observation gets noted. Only confirmed deviations become bugs.
Bug, defect, error, fault, failure
Different traditions use different vocabularies. The most common formal definitions:
- Error — a human mistake. A developer typing
>when they meant>=. - Defect / Bug / Fault — the resulting problem in the code or design. The wrong operator now lives in the source.
- Failure — the user-visible symptom. The form rejects a valid input because the operator is wrong.
Most teams use "bug" and "defect" interchangeably and rarely distinguish error from defect. The one distinction worth keeping is defect vs failure: a defect can exist for years without producing a failure (because nobody hits the affected case), and a failure can occur without a defect (e.g., a misconfigured environment).
What is not a bug
To keep the bug tracker focused, it helps to be explicit about what does not count:
- Feature requests. Things the system does not do but should.
- UX complaints without a violated expectation. "I don't like the colour" is feedback, not a defect.
- Environment-specific issues outside the supported matrix. "It doesn't work on Internet Explorer 9" matters only if IE9 is a supported browser.
- User error. The user typed their password wrong; the system rejected it correctly. Not a bug.
- Known limitations. Documented constraints are not bugs. They might be feature requests in disguise, but they are not regressions.
The line between "bug" and "feature request" is fuzzier than people admit. A useful test: would a reasonable user, reading the spec, expect this behaviour? If yes → bug. If no → feature.
Where bugs come from
The deeper you go in QA, the more you notice bugs cluster around a small number of root causes. The classics:
- Misunderstood requirements. The spec was ambiguous; the developer interpreted it one way; the tester another.
- Edge cases that were not considered. Empty inputs, max-length strings, leap days.
- Integration points. Two services agreeing on what "null" means, or not.
- State management. What happens when the user does X then Y then X again?
- Concurrency. Two requests arriving at the same time.
- Configuration drift. Staging and production differ in subtle ways.
Most bugs are not the result of bad code. They are the result of incomplete thinking — about requirements, about users, about timing, about failure modes. That is why testing exists.
What you should walk away with
A bug is a deviation from a defined expectation. Without expectation, there is no bug. Bug, defect, fault, failure — most of the time these are used loosely; the one distinction that matters is what is wrong in the code vs what the user sees go wrong. Up next: how a bug moves through the system once it has been reported — the bug lifecycle.