June 5, 2026

Error Reporting that Helps: Stop the Langoliers from Eating Your Users

 It has been over 18 years since I first published a mnemonic I created to help me test error handling and reporting in software systems: FAILURE.

Bad error reporting does not merely inconvenience users. It transfers the system’s uncertainty, ambiguity, and failure onto the user — in the form of wasted time, anxiety, mistrust, unnecessary work, and sometimes real harm.

Ambiguous and incorrect error messages send users on blind puzzle-solving side-quests.

They try again. They change inputs. They restart things. They search forums. They contact support. They wonder what they did wrong.

Often, the system made them do unnecessary work.

Often, some layer of the system already knew enough to say something more accurate, more timely, and more helpful.

That does not mean exposing raw internal errors, stack traces, implementation details, or sensitive information.

It often takes deliberate design and engineering work to preserve useful context, bubble it up through layers of the system, translate it into terms the user can act on, and decide what should or should not be revealed.

Sometimes opacity is appropriate. There are good reasons to avoid transparency when it would make systems, accounts, or the data entrusted to them less secure.

But “we cannot reveal everything” should not become an excuse for “we will reveal nothing useful.”

Usually, there is still something helpful we can say.

When software wastes people’s time, it is not wasting an abstract resource. It is consuming their life.

Five minutes here. An hour there. An afternoon lost to guessing what the system could have explained.

Ambiguous errors can become little Langoliers, eating chunks of people’s lives while they try to solve a puzzle they should never have been given.

Incorrect error reporting can also provoke needless anxiety and stress.

A message that implies data may have been lost, money may have been charged, access may have been revoked, or the user may have done something wrong can have a real emotional impact — especially when the message is inaccurate or incomplete.

And telling users to “try again” when some part of the stack already knows that what is being tried will never work is not optimism.

It is disrespect.

Good error handling should help people understand:

What happened? What was affected? What was not affected? Can I recover? What should I do next? Is this my problem, your problem, or nobody’s fault?

This is not merely a technical problem.

It is a human interaction problem.

It is a relationship problem.

When something goes wrong, the system is still communicating. It may communicate respect or indifference. Clarity or confusion. Accountability or evasion. Helpfulness or abandonment.

So I do not want to ask only, “Was an error message displayed?”

I want to ask:

What did the system make the user do? What did it make them wonder? What did it make them feel? What did it cost them? What did it help them recover? What did it make them trust less?

That is why I use the FAILURE heuristic:


F — Functional 

  • When something goes wrong, does the system still behave like a reliable partner? 
  • Does it detect the problem before the user wastes effort? 
  • Does it prevent the user from making the situation worse? 
  • Does it preserve the user’s work, choices, money, access, and trust? 
  • Does the handling of the error work for the user’s actual situation, not just for the system’s internal state?

A — Appropriate 

  • Does the system interrupt the user only when interruption is justified? 
  • Does it communicate at the moment the user needs to know, not merely when the system happens to notice? 
  • Does it choose a channel, placement, and level of urgency that fit the user’s context? 
  • Is the system appropriately opaque where transparency would create risk, without being needlessly vague where helpfulness is possible? 
  • Does it avoid making a small problem feel catastrophic? 
  • Does it avoid hiding a serious problem behind quiet failure, vague status, or false reassurance?

I — Impact 

  • Does the user understand what this means for them? 
  • Do they know whether their work, data, money, access, privacy, time, or reputation was affected? 
  • Do they know what was not affected? Do they know whether the action failed, succeeded, partially succeeded, or is still unknown? 
  • Does the system relieve uncertainty where it can, instead of making the user carry it?

L — Log 

  • Does the system remember enough about what happened so the user does not have to become the evidence collector? 
  • Can support or engineering investigate without asking the user to repeat painful, risky, or time-consuming steps? 
  • Are the right people able to see the right information at the right time? 
  • Is the user’s privacy respected while the problem is being diagnosed? 
  • Do the logs help the organization learn from the failure, or merely prove that something broke?

U — UI / Understandable 

  • Is the user expected to be clairvoyant? 
  • Does the system speak to the user as a person, not as a stack trace reader?
  • Does it explain the situation in terms of the user’s goal? 
  • Does the system translate internal knowledge into safe, useful user-facing information? 
  • Does it avoid making the user decode internal concepts, internal labels, or implementation details? 
  • Does it avoid blaming the user when the system does not know who or what caused the problem? 
  • Would the message still be understandable to someone who is tired, stressed, distracted, rushed, or unfamiliar with the system?

R — Recovery 

  • Does the user know what they can do next? 
  • Is the suggested next step realistic, available, and likely to help? 
  • Does the system avoid telling the user to retry when it already knows retrying will not work? 
  • Can the user save, undo, resume, escalate, or get help? When the user cannot fix the problem, does the system say who can? 
  • Does recovery feel like guidance, or like abandonment?

E — Emotions 

  • How is the system making the user feel at the moment something has gone wrong? 
  • Does it reduce confusion, anxiety, urgency, shame, and self-blame? 
  • Does it preserve dignity? Does it communicate honesty without panic? 
  • Does it acknowledge the user’s time and effort? 
  • Does it leave the user feeling helped, stranded, blamed, dismissed, manipulated, or respected?

A technically accurate error message can still be a poor user experience.

But an inaccurate, untimely, ambiguous, or unrecoverable error message can be worse than poor UX. It can waste people’s lives, increase their stress, erode their trust, and make them feel responsible for failures they did not cause.

The next time you write code to handle or report errors, or test error handling and reporting, do not stop at “was an error message displayed?”

Ask whether the error handling respects the user.

March 24, 2025

Why do software testers prefer dark mode?

When testing connections to Large Language Models, I often ask them to tell me a joke. 

Recently, GPT-4o-mini offered this:
"Why do software testers prefer dark mode?
Because light attracts bugs!"
It's a light joke, but it highlights a common misconception that software testers don't want to find bugs. This reminds me of Glenford Myers' critique in his 1976 book Software Reliability:
“One usually encounters a definition such as,
‘Testing is the process of confirming that a program is correct.
It is the demonstration that errors are not present.’

The main trouble with this definition is that it is totally wrong;
in fact, it almost defines the antonym of testing.”
DEMONSTRATING that software can work under specific conditions is part of testing -- but it is just the start. 

Modern software development thrives on automated DEMONSTRATIONS. They help confirm what we believe to be true and detect regressions quickly. But if we stop at DEMONSTRATION, we miss the chance of DISCOVERING bugs that will bug people we care about. 

Testing isn't just about DEMONSTRATING that software can work -- it's about DISCOVERING how it may not work as desired. 

  • Test to DISCOVER what is undocumented
  • Test to DISCOVER what is unsafe
  • Test to DISCOVER what is unintended
  • Test to DISCOVER what is unpredictable
  • Test to DISCOVER what is unknown

If you aren't seeking to DISCOVER , you may not be testing.

Don't test in dark mode. 

Shine a light to attract the bugs before they attract your stakeholders' ire.

October 31, 2013

Is Healthcare.gov security now fixed?




I first attempted to use HealthCare.gov to learn about options for covering my granddaughter, who is not covered by my employer-subsidized insurance. I encountered the same kinds of account creation issues others have reported, but I decided to turn on my web browser’s built-in developer tools to see if I might see details as to why form submissions were failing. I quickly discovered that the main browser window would often display a status other than what was actually occurring. For example, the form submission would fail to get a response from the server but the user interface would report that the form was submitted. Once I saw this behavioral mismatch between what was displayed in the browser and what was actually happening, I kept developer tools on as I used the site.


I do not consider using developer tools to watch data moving in and out of my own computer to be “hacking.” I have NOT “hacked” Healthcare.gov. I have only observed what is sent to my computer. I have NOT attempted to gain unauthorized access to Healthcare.gov accounts. Attempting to gain unauthorized access would be both unethical and illegal. Please don't try it.


While watching the interactions between my web browser and the Healthcare.gov servers, I saw information being sent to my computer that likely should not have been sent by the server. After I was told that Healthcare.gov will not take reports of security concerns, I started blogging them.




Then I came across a very serious issue.


I discovered a design defect that subsequently led to me receiving a great deal of media attention. Little did I know that my findings would be mentioned in Wednesday's congressional hearings:




ESHOO: On the issue of security, there was a security breach that arose recently, that I read about at any rate. And what I think is very important here, because the issue of privacy has been raised, and I think that that has been answered. Very importantly, there isn't any health information in these systems. But there is financial information, so my question to you is, has a security wall been built, and are you confident that it is there and that it will actually secure the financial information that applicants have to disclose?


SEBELIUS: Yes, ma'am, I -- I would tell you that there was not a breach, there was a blog by a sort of skilled hacker that if a certain series of incidents occurred, you could possibly get in and obtain somebody's personally identifiable...


(CROSSTALK) ESHOO: But isn't that telling? Isn't that telling?


SEBELIUS: And we immediately corrected that problem, so there wasn't a -- it was a theoretical problem that was immediately fixed. I would tell you we are storing the minimum amount of data, because we think that's very important. The hub is not a data collector. It is actually using data centers at the IRS, at Homeland Security, at Social Security to verify information, but it stores none of that data, so we don't want to be.....




Secretary Sebelius is correct: I did not breach or exploit any of the vulnerabilities that I reported on my blog. And it is nice that she thinks I’m “sort of skilled” as a hacker, when I’m actually a highly-experienced software tester.


I identified a series of steps that could be easily automated to collect usernames, password reset codes, security questions, and email addresses from the system -- without any kind of authentication.


Attackers could use this information to go phishing. Exposing this information gives attackers sufficient information to gain trust and trick people into disclosing their security question answers.


If I were a malicious phisherman, I might send users email that directs them to a site masquerading as HealthCare.gov, and then ask victims to provide their security questions in order to revalidate their account. After collecting this information, I could then reset the password and access information the user provided to HealthCare.gov.


I found this issue last Thursday night (October 24th). I notified HealthCare.gov customer service immediately.  The next morning, I found someone who could help pass information about my discovery to people within HHS. CMS patched the most serious hole the same day, and made further changes on Monday before making a public statement about the issue.





While I am appalled that the issue existed in the first place, I applaud the quick response.




Monday night, after CMS publicly confirmed the fix, I took a quick look at the new "fixed" password reset functionality.



I saw a couple of positive changes:


  1. The password reset code is no longer returned to the web browser. This closes the biggest hole. Exploiting weaknesses in the password reset system will now require that password reset codes be obtained by intercepting email, or some other mechanism.


  1. The system asks for security question answers and a new password before submitting the request. This slows down manual security question guessing attempts, but will have little impact on an automated attack.



I also saw that many potential security issues still exist:


  1. The system still confirms whether a username or email address exists in the error messages returned by the underlying services. Given that these are not public identifiers in the Insurance Marketplace, these should not be revealed. (As of 11/07, this still exists.)


  1. The system still transmits both the username and password reset code via email. Email is generally not a secure means of communication. A more secure way to do this would be to send the user only half of the equation: the reset code; and then prompt the user for the username after they follow the reset link. (As of 11/08, this still exists.)


  1. The password reset code still stays the same with each request (and is the same code used to initially activate the account). A more secure way to do this would be to change the code each time a password reset is requested or a password is reset; and in the case that a system contains sensitive information like this one does: put a time limit in which the reset code may be used. (As of 11/13, this appears to have been fixed. Reset codes are changing and old ones don't work.)


  1. When requesting a password reset, the username and password reset code are still sent to 3rd party analytics companies. Even if these companies can be trusted to not misuse the data, this likely violates their terms of use and privacy policies. And if these 3rd parties aren't expecting personal information, they may not protect it as they would protect personal information. (As of 10/31, this appears to have been fixed.)


  1. If any of the above (or other) issues lead to a username or password reset code being compromised, the security questions and email address associated with the account can still be retrieved from the system without authorization.


  1. In the unfortunate event that an account is compromised:


    1. An attacker can change the email address associated with the account without triggering notification of the email change to the user. Once this is done, other account information can be changed without notifying the owner of the account. (As of 11/05, this still exists.)


    1. The personal information used to validate a user's identity is returned to the browser each time a user logs into a system. This data is both retained and returned to the browser when it should no longer be needed. Returning it to the browser each time a user logs into the system increases the potential damage should an account be compromised.  This data includes the personal information the account owner provided to verify their identity -- sufficient information to steal another’s identify. This also include all information entered into an insurance application for each person on the application (eg: names, DOB, SSNs, disability, pregnancy, finanical) and data retrieved from back-end systems (eg: employer, and income, and last paycheck details). (As of 11/13, the identify verification data is no longer returned to the browser; however, the personal information in the insurance application is still returned to the browser.)






Have you heard?

SLAVITT: Our systems don't hold data. They just transport data through it.

ROGERS: You don't have to hold it to protect it.


Both Secretary Kathleen Sebelius and Andy Slavitt, an executive VP at QSSI (the company tasked with fixing Healthcare.gov) have downplayed security concerns. They have suggested that personal information is not at risk because The Hub, the Healthcare.gov front end, does not store information; but rather, transports information. A system is only as secure as its weakest link. If front-end security is poor, then no amount of back-end security can protect information passing through the front end.

Even if Healthcare.gov doesn't store information, it returns personal information to the browser. As outlined above, the data I once provided to verify my identity is sent to my computer each time I login to Healthcare.gov -- long after the identity verification has been completed. This information includes name, address, date of birth, phone number, and Social Security Number. It also returns data retrieved from back-end systems; including, employer, income, last paycheck details, and more.



Much of the work required to exploit these vulnerabilities can be automated.


Many of these vulnerabilities are rather benign when considered individually. However, they quickly become more serious concerns if we consider how they may be combined and the exploits automated.




I have discovered several additional vulnerabilities while using the site.


  1. The email validation system demonstrated the same flaw as the password reset system: It returned the activation code (which is the same as the password reset code) to the browser; enabling one to create an account using an email address they do not own. (As of 11/5, this appears to be fixed.)


  1. My username and questionnaire answers were sent over the Internet without encryption under an error condition that also led to my profile information not being displayed. (As of 11/08, this still exists.)


  1. The system returned Java stack traces to the browser; potentially revealing information about the internal workings or data of the system that could be exploited to find weaknesses in security. (As of 11/05, this still exists.)


  1. The security questions ask for things that are likely to be known by one's friends, family, or ex -- and are the sorts of things many will post on Facebook or other social media. (This morning, HHS Secretary Sebelius referred to these questions as "personalized questions that can only be verified by you". They aren't.) (As of 11/08, this still exists.)


We can only speculate at what other security vulnerabilities might be found by someone willing to attempt to gain unauthorized access.



But wait, there's more!

UPDATE 10/31:

  1. Healthcare.gov returns the username for an account when given a user's real name and email address. (This appeared to be fixed on 11/06, then reappeared on 11/08. As of 11/10, it appears to have been fixed again.)
  2. Healthcare.gov returns the security questions for an account when given a username. (As of 11/11, this appears to have been fixed. I last say it on 11/08.)



No other authentication is required. Although this doesn't provide an attacker with the password reset code, it exposes information that should be kept private and provides sufficient information to make phishing relatively easy.







Conclusion


I am very happy that the most egregious issue was immediately fixed.


Others issues remain.


The vulnerabilities I've listed above are defects that should not make it to production.  It doesn't take a security expert or “super hacker” to exploit these vulnerabilities.


This is basic web security.  Most of these are the kinds of issues that competent web developers try to avoid; and in the rare case that they are created, are usually found by competent testers.


Rather than individual incompetence, these issues might suggest a fractured development team -- where the developers building the components don't know how they are used in the system and therefore do not have sufficient situational awareness to understand the security implications of their decisions. Still, someone has to assemble the components and the system as a whole should be tested for security. Given that I don't know what's going on within the project, I can only speculate. I have; however, seen enough to be concerned.


The volume of users, the nature of the data presumed in the system, and the political attention all contribute to making HealthCare.gov a target of interest to attackers -- of higher interest than the typical web site. This demands a higher standard. This requires that security be made a priority throughout design, implementation, testing, and monitoring of the system.


I am still concerned about Healthcare.gov security. It should concern all of us.