---
title: Signal an expired system hash
summary: Construct the SystemHashExpiredException that a consumer throws once it decides a recovered create date has expired.
status: draft
owner: SAIF Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.HashUtil
reference_type: package
operation_id: OP-HU-05
trigger: Consumer decides a hash has expired
---

# Signal an expired system hash

This operation constructs `SystemHashExpiredException` with a fixed-format message containing the hash's embedded create date and the date it was evaluated against. HashUtil only defines the exception type and formats its message — the lifetime comparison and the decision to throw belong entirely to the calling consumer. In-repo, `SystemHashService.RemoveSystemHashSaltAndValidateLifetime` throws this exception after calling `BlandHash` (OP-HU-04) and determining the recovered create date falls outside the allowed lifetime window.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-HU-05 |
| **Trigger** | Thrown by a consumer after it decides a recovered create date has expired (in-repo: `SystemHashService.RemoveSystemHashSaltAndValidateLifetime`) |
| **Inputs** | `nowDate`, `hashDate` (both `DateTime`) |
| **Outputs** | `SystemHashExpiredException` with a fixed-format message |
| **Primary components** | `SystemHashExpiredException.SystemHashExpiredException(DateTime nowDate, DateTime hashDate)` |
| **Entry point** | `src/SAIF.NetCore.HashUtil/SAIF.NetCore.HashUtil/SystemHashExpiredException.cs` |

## Steps

1. Format both `nowDate` and `hashDate` with the fixed pattern `MM/dd/yyyy hh:mm:ss.ffffff` (12-hour clock, no AM/PM designator) and pass the composed message — "The supplied system hash token has expired and is no longer valid. {hashDate} was provided with the hash token and evaluated against the current date of {nowDate}." — to the base `Exception(string)` constructor ([BR-HU-09](../business-rules.md#br-hu-09-fixed-format-expiry-message)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Consumer decides hash has expired]) --> S1["Format nowDate and hashDate as<br>MM/dd/yyyy hh:mm:ss.ffffff"]
	S1 --> S2[Compose fixed expiry message]
	S2 --> S3[Pass message to base Exception constructor]
	S3 --> EndOk(["SystemHashExpiredException constructed<br>and thrown by consumer"])
```

## Failure and edge-case behavior
- The 12-hour clock format (`hh`) carries no AM/PM designator, so the formatted times in the message are ambiguous between morning and evening occurrences ([BR-HU-09](../business-rules.md#br-hu-09-fixed-format-expiry-message)).
- The lifetime comparison that decides whether to construct and throw this exception is implemented entirely outside HashUtil, in `SAIF.NetCore.SystemHash`'s `SystemHashService.RemoveSystemHashSaltAndValidateLifetime`.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `src/SAIF.NetCore.HashUtil/SAIF.NetCore.HashUtil/SystemHashExpiredException.cs`
- `src/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SystemHashService.cs`
